From e9c753d2a901ed52943383b35bc2e797e588a6a6 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Mon, 21 Jul 2025 08:45:13 +0000 Subject: [PATCH] BREAKING_CHANGE(routing): refactor route configuration to support multiple targets --- certs/static-route/meta.json | 6 +- changelog.md | 8 + package.json | 2 +- test-output.log | 2749 +++++++++++++++++ test/core/routing/test.path-matcher.ts | 4 +- .../utils/test.shared-security-manager.ts | 4 +- test/test.acme-route-creation.ts | 2 +- test/test.acme-timing-simple.ts | 2 +- test/test.acme-timing.ts | 4 +- test/test.certificate-acme-update.ts | 4 +- test/test.certificate-provision.ts | 20 +- test/test.certificate-provisioning.ts | 10 +- test/test.certificate-simple.ts | 2 +- test/test.cleanup-queue-bug.node.ts | 2 +- test/test.connect-disconnect-cleanup.node.ts | 8 +- ...t.connection-cleanup-comprehensive.node.ts | 12 +- test/test.connection-forwarding.ts | 16 +- test/test.connection-limits.node.ts | 8 +- test/test.fix-verification.ts | 4 +- test/test.forwarding-fix-verification.ts | 4 +- test/test.forwarding-regression.ts | 4 +- test/test.forwarding.ts | 2 +- test/test.http-fix-unit.ts | 6 +- test/test.http-fix-verification.ts | 4 +- test/test.http-forwarding-fix.ts | 4 +- test/test.http-port8080-forwarding.ts | 4 +- test/test.http-port8080-simple.ts | 6 +- test/test.httpproxy.function-targets.ts | 20 +- test/test.keepalive-support.node.ts | 6 +- test/test.long-lived-connections.ts | 4 +- test/test.metrics-new.ts | 4 +- test/test.nftables-forwarding.ts | 8 +- test/test.nftables-manager.ts | 12 +- test/test.nftables-status.ts | 2 +- test/test.port-forwarding-fix.ts | 4 +- test/test.port-mapping.ts | 4 +- test/test.port80-management.node.ts | 8 +- test/test.proxy-chain-cleanup.node.ts | 8 +- test/test.proxy-chain-simple.node.ts | 8 +- test/test.proxy-chaining-accumulation.node.ts | 16 +- test/test.rapid-retry-cleanup.node.ts | 4 +- test/test.route-callback-simple.ts | 4 +- test/test.route-security-integration.ts | 12 +- test/test.route-security-unit.ts | 4 +- test/test.route-security.ts | 12 +- test/test.route-update-callback.node.ts | 8 +- test/test.router.ts | 4 +- test/test.smartacme-integration.ts | 4 +- test/test.stuck-connection-cleanup.node.ts | 2 +- test/test.websocket-keepalive.node.ts | 4 +- test/test.zombie-connection-cleanup.node.ts | 8 +- 51 files changed, 2914 insertions(+), 157 deletions(-) create mode 100644 test-output.log diff --git a/certs/static-route/meta.json b/certs/static-route/meta.json index 139e279..84e9574 100644 --- a/certs/static-route/meta.json +++ b/certs/static-route/meta.json @@ -1,5 +1,5 @@ { - "expiryDate": "2025-10-01T02:31:27.435Z", - "issueDate": "2025-07-03T02:31:27.435Z", - "savedAt": "2025-07-03T02:31:27.435Z" + "expiryDate": "2025-10-18T13:15:48.916Z", + "issueDate": "2025-07-20T13:15:48.916Z", + "savedAt": "2025-07-20T13:15:48.916Z" } \ No newline at end of file diff --git a/changelog.md b/changelog.md index f1a3f3f..9ab5953 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +## 2025-07-20 - 20.0.0 - BREAKING_CHANGE(routing) +Refactor route configuration to support multiple targets + +- Changed route action configuration from single `target` to `targets` array +- Enables load balancing and failover capabilities with multiple upstream targets +- Updated all test files to use new `targets` array syntax +- Automatic certificate metadata refresh + ## 2025-06-01 - 19.5.19 - fix(smartproxy) Fix connection handling and improve route matching edge cases diff --git a/package.json b/package.json index 9d8491a..db09d44 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@push.rocks/smartproxy", - "version": "19.6.17", + "version": "20.0.0", "private": false, "description": "A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.", "main": "dist_ts/index.js", diff --git a/test-output.log b/test-output.log new file mode 100644 index 0000000..bb7bf6d --- /dev/null +++ b/test-output.log @@ -0,0 +1,2749 @@ + +> @push.rocks/smartproxy@19.6.17 test /mnt/data/lossless/push.rocks/smartproxy +> (tstest test/**/test*.ts --verbose --timeout 60 --logfile) + + +πŸ” Test Discovery + Mode: glob + Pattern: test/**/test*.ts + Found: 78 test file(s) + +▢️ test/core/routing/test.domain-matcher.ts (1/78) + Runtime: node.js + Test starting: DomainMatcher - exact match + βœ… DomainMatcher - exact match (0ms) + Test starting: DomainMatcher - case insensitive + βœ… DomainMatcher - case insensitive (0ms) + Test starting: DomainMatcher - wildcard matching + βœ… DomainMatcher - wildcard matching (0ms) + Test starting: DomainMatcher - FQDN normalization + βœ… DomainMatcher - FQDN normalization (0ms) + Test starting: DomainMatcher - edge cases + βœ… DomainMatcher - edge cases (0ms) + Test starting: DomainMatcher - specificity calculation + βœ… DomainMatcher - specificity calculation (0ms) + Test starting: DomainMatcher - findAllMatches + βœ… DomainMatcher - findAllMatches (0ms) + Summary: 7/7 PASSED in 1.3s + +▢️ test/core/routing/test.ip-matcher.ts (2/78) + Runtime: node.js + Test starting: IpMatcher - exact match + βœ… IpMatcher - exact match (0ms) + Test starting: IpMatcher - CIDR notation + βœ… IpMatcher - CIDR notation (0ms) + Test starting: IpMatcher - wildcard matching + βœ… IpMatcher - wildcard matching (0ms) + Test starting: IpMatcher - range matching + βœ… IpMatcher - range matching (0ms) + Test starting: IpMatcher - IPv6-mapped IPv4 + βœ… IpMatcher - IPv6-mapped IPv4 (0ms) + Test starting: IpMatcher - IP validation + βœ… IpMatcher - IP validation (0ms) + Test starting: IpMatcher - isAuthorized + βœ… IpMatcher - isAuthorized (0ms) + Test starting: IpMatcher - specificity calculation + βœ… IpMatcher - specificity calculation (1ms) + Test starting: IpMatcher - edge cases + βœ… IpMatcher - edge cases (0ms) + Summary: 9/9 PASSED in 1.3s + +▢️ test/core/routing/test.path-matcher.ts (3/78) + Runtime: node.js + Test starting: PathMatcher - exact match + βœ… PathMatcher - exact match (0ms) + Test starting: PathMatcher - no match + βœ… PathMatcher - no match (0ms) + Test starting: PathMatcher - parameter extraction + βœ… PathMatcher - parameter extraction (0ms) + Test starting: PathMatcher - multiple parameters + βœ… PathMatcher - multiple parameters (1ms) + Test starting: PathMatcher - wildcard matching + Error details: + Expected value to equal "users/123/profile" +  + Diff: +  Line 1: - users/123/profile +  Line 1: + /users/123/profile + ❌ PathMatcher - wildcard matching (0ms) + ⟦TSTEST:META:{"time":4,"retry":0,"error":{"message":"Expected value to equal \"users/123/profile\"","stack":"Error: Expected value to equal \"users/123/profile\"\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Assertion.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Assertion.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at Assertion.toEqual (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:332:17)\n at Proxy. (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.expect.wrapper.ts:33:38)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/core/routing/test.path-matcher.ts:35:32)\n at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26)\n at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34)\n at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39)"}}⟧ + ⟦TSTEST:ERROR⟧ + { + "testNumber": 5, + "error": { + "message": "Expected value to equal \"users/123/profile\"", + "stack": "Error: Expected value to equal \"users/123/profile\"\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Assertion.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Assertion.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at Assertion.toEqual (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:332:17)\n at Proxy. (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.expect.wrapper.ts:33:38)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/core/routing/test.path-matcher.ts:35:32)\n at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26)\n at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34)\n at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39)" + } + } + Error details: + Error: Expected value to equal "users/123/profile" + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Assertion.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Assertion.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at Assertion.toEqual (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:332:17) + at Proxy. (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.expect.wrapper.ts:33:38) + at (/mnt/data/lossless/push.rocks/smartproxy/test/core/routing/test.path-matcher.ts:35:32) + at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26) + at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34) + at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39) + Error: Expected value to equal "users/123/profile" + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Assertion.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Assertion.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at Assertion.toEqual (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:332:17) + at Proxy. (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.expect.wrapper.ts:33:38) + at (/mnt/data/lossless/push.rocks/smartproxy/test/core/routing/test.path-matcher.ts:35:32) + at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26) + at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34) + at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39) + Test starting: PathMatcher - mixed parameters and wildcards + Error details: + Expected value to equal "users/123" +  + Diff: +  Line 1: - users/123 +  Line 1: + /users/123 + ❌ PathMatcher - mixed parameters and wildcards (0ms) + ⟦TSTEST:META:{"time":0,"retry":0,"error":{"message":"Expected value to equal \"users/123\"","stack":"Error: Expected value to equal \"users/123\"\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Assertion.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Assertion.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at Assertion.toEqual (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:332:17)\n at Proxy. (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.expect.wrapper.ts:33:38)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/core/routing/test.path-matcher.ts:42:32)\n at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26)\n at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34)\n at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39)"}}⟧ + ⟦TSTEST:ERROR⟧ + { + "testNumber": 6, + "error": { + "message": "Expected value to equal \"users/123\"", + "stack": "Error: Expected value to equal \"users/123\"\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Assertion.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Assertion.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at Assertion.toEqual (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:332:17)\n at Proxy. (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.expect.wrapper.ts:33:38)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/core/routing/test.path-matcher.ts:42:32)\n at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26)\n at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34)\n at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39)" + } + } + Error details: + Error: Expected value to equal "users/123" + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Assertion.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Assertion.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at Assertion.toEqual (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:332:17) + at Proxy. (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.expect.wrapper.ts:33:38) + at (/mnt/data/lossless/push.rocks/smartproxy/test/core/routing/test.path-matcher.ts:42:32) + at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26) + at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34) + at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39) + Error: Expected value to equal "users/123" + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Assertion.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Assertion.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at Assertion.toEqual (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:332:17) + at Proxy. (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.expect.wrapper.ts:33:38) + at (/mnt/data/lossless/push.rocks/smartproxy/test/core/routing/test.path-matcher.ts:42:32) + at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26) + at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34) + at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39) + Test starting: PathMatcher - trailing slash normalization + βœ… PathMatcher - trailing slash normalization (0ms) + Test starting: PathMatcher - root path handling + βœ… PathMatcher - root path handling (0ms) + Test starting: PathMatcher - specificity calculation + βœ… PathMatcher - specificity calculation (1ms) + Test starting: PathMatcher - findAllMatches + βœ… PathMatcher - findAllMatches (1ms) + Test starting: PathMatcher - edge cases + βœ… PathMatcher - edge cases (0ms) + Test 5 failed with status error: + || PathMatcher - wildcard matching + || for more information please take a look the logs above + Test 6 failed with status error: + || PathMatcher - mixed parameters and wildcards + || for more information please take a look the logs above + Summary: 9 passed, 2 failed of 11 tests in 1.3s + +▢️ test/core/utils/test.async-utils.ts (4/78) + Runtime: node.js + Test starting: delay should pause execution for specified milliseconds + βœ… delay should pause execution for specified milliseconds (102ms) + Test starting: retryWithBackoff should retry failed operations + βœ… retryWithBackoff should retry failed operations (31ms) + Test starting: retryWithBackoff should throw after max attempts + βœ… retryWithBackoff should throw after max attempts (11ms) + Test starting: withTimeout should complete operations within timeout + βœ… withTimeout should complete operations within timeout (50ms) + Test starting: withTimeout should throw on timeout + βœ… withTimeout should throw on timeout (50ms) + Test starting: parallelLimit should respect concurrency limit + βœ… parallelLimit should respect concurrency limit (151ms) + Test starting: debounceAsync should debounce function calls + βœ… debounceAsync should debounce function calls (151ms) + Test starting: AsyncMutex should ensure exclusive access + βœ… AsyncMutex should ensure exclusive access (32ms) + Test starting: CircuitBreaker should open after failures + βœ… CircuitBreaker should open after failures (151ms) + Summary: 9/9 PASSED in 2.0s + +▢️ test/core/utils/test.binary-heap.ts (5/78) + Runtime: node.js + Test starting: should create empty heap + βœ… should create empty heap (1ms) + Test starting: should insert and extract in correct order + βœ… should insert and extract in correct order (1ms) + Test starting: should work with custom objects and comparator + βœ… should work with custom objects and comparator (0ms) + Test starting: should support reverse order (max heap) + βœ… should support reverse order (max heap) (0ms) + Test starting: should extract by predicate + βœ… should extract by predicate (0ms) + Test starting: should extract by key + βœ… should extract by key (0ms) + Test starting: should throw when using key operations without extractKey + βœ… should throw when using key operations without extractKey (0ms) + Test starting: should handle duplicates correctly + βœ… should handle duplicates correctly (0ms) + Test starting: should convert to array without modifying heap + βœ… should convert to array without modifying heap (0ms) + Test starting: should clear the heap + βœ… should clear the heap (0ms) + Test starting: should handle complex extraction patterns + βœ… should handle complex extraction patterns (0ms) + Summary: 11/11 PASSED in 1.2s + +▢️ test/core/utils/test.fs-utils.ts (6/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< + Test starting: should create and check directory existence + βœ… should create and check directory existence (1ms) + Test starting: should write and read text files + βœ… should write and read text files (2ms) + Test starting: should write and read JSON files + βœ… should write and read JSON files (1ms) + Test starting: should copy files + βœ… should copy files (1ms) + Test starting: should move files + βœ… should move files (1ms) + Test starting: should list files in directory + βœ… should list files in directory (0ms) + Test starting: should list files with full paths + βœ… should list files with full paths (1ms) + Test starting: should get file stats + βœ… should get file stats (0ms) + Test starting: should handle non-existent files gracefully + βœ… should handle non-existent files gracefully (0ms) + Test starting: should remove files + βœ… should remove files (1ms) + Test starting: should ensure file exists + βœ… should ensure file exists (0ms) + Test starting: should recursively list files + βœ… should recursively list files (1ms) + Test starting: should clean up test directory + βœ… should clean up test directory (1ms) + Summary: 13/13 PASSED in 2.2s + +▢️ test/core/utils/test.ip-utils.ts (7/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< + Test starting: ip-utils - normalizeIP + βœ… ip-utils - normalizeIP (1ms) + Test starting: ip-utils - isGlobIPMatch + βœ… ip-utils - isGlobIPMatch (3ms) + Test starting: ip-utils - isIPAuthorized + βœ… ip-utils - isIPAuthorized (1ms) + Test starting: ip-utils - isPrivateIP + βœ… ip-utils - isPrivateIP (0ms) + Test starting: ip-utils - isPublicIP + βœ… ip-utils - isPublicIP (0ms) + Test starting: ip-utils - cidrToGlobPatterns + βœ… ip-utils - cidrToGlobPatterns (0ms) + Summary: 6/6 PASSED in 2.3s + +▢️ test/core/utils/test.lifecycle-component.ts (8/78) + Runtime: node.js + Test starting: should manage timers properly + βœ… should manage timers properly (202ms) + Test starting: should manage event listeners properly + βœ… should manage event listeners properly (0ms) + Test starting: should prevent timer execution after cleanup + βœ… should prevent timer execution after cleanup (150ms) + Test starting: should handle child components + βœ… should handle child components (100ms) + Test starting: should handle multiple cleanup calls gracefully + βœ… should handle multiple cleanup calls gracefully (0ms) + Test starting: should clear specific timers + βœ… should clear specific timers (151ms) + Test starting: should clear specific intervals + βœ… should clear specific intervals (220ms) + Test starting: should handle once event listeners + βœ… should handle once event listeners (1ms) + Test starting: should not create timers when shutting down + βœ… should not create timers when shutting down (50ms) + Summary: 9/9 PASSED in 2.1s + +▢️ test/core/utils/test.shared-security-manager.ts (9/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< + Test starting: Shared Security Manager + βœ… Shared Security Manager (1ms) + Summary: 1/1 PASSED in 2.2s + +▢️ test/core/utils/test.validation-utils.ts (10/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< + Test starting: validation-utils - isValidPort + βœ… validation-utils - isValidPort (0ms) + Test starting: validation-utils - isValidDomainName + βœ… validation-utils - isValidDomainName (0ms) + Test starting: validation-utils - isValidEmail + βœ… validation-utils - isValidEmail (0ms) + Test starting: validation-utils - isValidCertificate + βœ… validation-utils - isValidCertificate (1ms) + Test starting: validation-utils - isValidPrivateKey + βœ… validation-utils - isValidPrivateKey (0ms) + Test starting: validation-utils - validateDomainOptions + βœ… validation-utils - validateDomainOptions (0ms) + Test starting: validation-utils - validateAcmeOptions + βœ… validation-utils - validateAcmeOptions (0ms) + Summary: 7/7 PASSED in 2.3s + +▢️ test/test.acme-http-challenge.ts (11/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: should handle HTTP requests on port 80 for ACME challenges +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 18080 is used by 1 routes: acme-test-route +   info:  SmartProxy starting with 1 ports: 18080 +   info:  SmartProxy -> OK: Now listening on port 18080 +   info:  No routes require certificate management +  debug  MetricsCollector started +   info:  New connection from ::ffff:127.0.0.1 on port 18080. Active connections: 1 +   info:  Handling socket-handler action for route acme-test-route +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 18080 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 18080 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… should handle HTTP requests on port 80 for ACME challenges (27ms) + Test starting: should parse HTTP headers correctly +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 18081 is used by 1 routes: header-test-route +   info:  SmartProxy starting with 1 ports: 18081 +   info:  SmartProxy -> OK: Now listening on port 18081 +   info:  No routes require certificate management +  debug  MetricsCollector started +  debug  Connection 1zmgol0smz7892s0rtaqq closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 18081. Active connections: 1 +   info:  Handling socket-handler action for route header-test-route +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 18081 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 18081 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  [SUMMARY] 1 HttpProxy connections terminated in 0s +   info:  SmartProxy shutdown complete. + βœ… should parse HTTP headers correctly (5ms) +  debug  Connection 7d9dtenko8n68ci30cnx8u closed during immediate routing: immediate-route-client_closed +   info:  [SUMMARY] 1 HttpProxy connections terminated in 1s + Summary: 2/2 PASSED in 3.3s + +▢️ test/test.acme-http01-challenge.ts (12/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: should correctly handle HTTP-01 challenge requests with initial data chunk +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 8080 is used by 1 routes: acme-challenge-route +   info:  SmartProxy starting with 1 ports: 8080 +   info:  SmartProxy -> OK: Now listening on port 8080 +   info:  No routes require certificate management +  debug  MetricsCollector started +   info:  New connection from ::ffff:127.0.0.1 on port 8080. Active connections: 1 +   info:  Handling socket-handler action for route acme-challenge-route + Received request: GET /.well-known/acme-challenge/test-acme-http01-challenge-token +  debug  Connection ctk31t255pd9c33wgs7iol closed during immediate routing: immediate-route-client_closed +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8080 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8080 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  [SUMMARY] 1 HttpProxy connections terminated in 0s +   info:  SmartProxy shutdown complete. + βœ… should correctly handle HTTP-01 challenge requests with initial data chunk (113ms) + Test starting: should return 404 for non-existent challenge tokens +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 8081 is used by 1 routes: acme-challenge-route +   info:  SmartProxy starting with 1 ports: 8081 +   info:  SmartProxy -> OK: Now listening on port 8081 +   info:  No routes require certificate management +  debug  MetricsCollector started +   info:  New connection from ::ffff:127.0.0.1 on port 8081. Active connections: 1 +   info:  Handling socket-handler action for route acme-challenge-route +  debug  Connection b85l4hhzztejnaxzf4lee9 closed during immediate routing: immediate-route-client_closed +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8081 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8081 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  [SUMMARY] 1 HttpProxy connections terminated in 0s +   info:  SmartProxy shutdown complete. + βœ… should return 404 for non-existent challenge tokens (103ms) + Summary: 2/2 PASSED in 3.4s + +▢️ test/test.acme-route-creation.ts (13/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: should create ACME challenge route +   info:  Route manager configured with 2 routes across 2 ports +   info:  Updated RouteManager with 2 routes +  debug  Port 18443 is used by 1 routes: secure-route +  debug  Port 18080 is used by 1 routes: acme-challenge +   info:  SmartProxy starting with 2 ports: 18080, 18443 +   info:  SmartProxy -> OK: Now listening on port 18080 +   info:  SmartProxy -> OK: Now listening on port 18443 +   info:  No routes require certificate management +  debug  MetricsCollector started +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 18080 reference count decreased to 0 +  debug  Port 18443 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 18080 +   info:  SmartProxy -> Stopped listening on port 18443 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… should create ACME challenge route (6ms) + Test starting: should handle HTTP request parsing correctly +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 18090 is used by 1 routes: test-static +   info:  SmartProxy starting with 1 ports: 18090 +   info:  SmartProxy -> OK: Now listening on port 18090 +   info:  No routes require certificate management +  debug  MetricsCollector started +   info:  New connection from ::ffff:127.0.0.1 on port 18090. Active connections: 1 +   info:  Handling socket-handler action for route test-static +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 18090 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 18090 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… should handle HTTP request parsing correctly (12ms) +  debug  Connection uczlsw6loqkmw2nt7506mi closed during immediate routing: immediate-route-client_closed +   info:  [SUMMARY] 1 HttpProxy connections terminated in 0s + Summary: 2/2 PASSED in 2.3s + +▢️ test/test.acme-simple.ts (14/78) + Runtime: node.js + Test starting: should parse HTTP requests correctly + Test server listening on port 18091 + βœ… should parse HTTP requests correctly (8ms) + Test starting: should configure ACME challenge route + βœ… should configure ACME challenge route (1ms) + Summary: 2/2 PASSED in 1.2s + +▢️ test/test.acme-state-manager.node.ts (15/78) + Runtime: node.js + Test starting: AcmeStateManager should track challenge routes correctly + βœ… AcmeStateManager should track challenge routes correctly (0ms) + Test starting: AcmeStateManager should track port allocations + βœ… AcmeStateManager should track port allocations (0ms) + Test starting: AcmeStateManager should select primary route by priority + βœ… AcmeStateManager should select primary route by priority (0ms) + Test starting: AcmeStateManager should handle clear operation + βœ… AcmeStateManager should handle clear operation (1ms) + Summary: 4/4 PASSED in 1.2s + +▢️ test/test.acme-timing-simple.ts (16/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: should defer certificate provisioning until ports are ready +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +   WARN ->  1 configuration warnings found +   WARN ->  Port 80 is not configured for any routes but is needed for ACME challenges. Add a route listening on port 80 or ensure it's accessible for HTTP-01 challenges. +  debug  Port 8443 is used by 1 routes: test-route +   info:  SmartProxy starting with 1 ports: 8443 +   info:  SmartProxy -> OK: Now listening on port 8443 + Ports are now listening +   info:  Using route-level ACME configuration from route 'test-route' with email: test@local.dev + Creating mock cert manager + Mock cert manager initialized +   info:  Starting certificate provisioning now that ports are ready + Mock certificate provisioning (ports are ready) +  debug  MetricsCollector started + Operation order: [ + 'ports-starting', + 'ports-ready', + 'create-cert-manager', + 'cert-manager-init', + 'cert-provisioning' + ] +   info:  SmartProxy shutting down... +   info:  Certificate manager stopped +   info:  NFTablesManager stopped +  debug  Port 8443 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8443 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… should defer certificate provisioning until ports are ready (6ms) + Summary: 1/1 PASSED in 2.3s + +▢️ test/test.acme-timing.ts (17/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: should defer certificate provisioning until after ports are listening +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +   WARN ->  1 configuration warnings found +   WARN ->  Port 8080 is not configured for any routes but is needed for ACME challenges. Add a route listening on port 8080 or ensure it's accessible for HTTP-01 challenges. +  debug  Port 8443 is used by 1 routes: test-acme-route +   info:  SmartProxy starting with 1 ports: 8443 + [INFO] Route manager configured with 0 routes across 0 ports  + [INFO] Updated RouteManager with 0 routes  + [WARN] CertificateManager is deprecated - use SmartCertManager instead  + [INFO] Loaded default certificates from filesystem (sync - deprecated)  + Initialized HttpProxy on port 8845 + [INFO] Updating route configurations (0 routes)  + [INFO] Route manager configured with 0 routes across 0 ports  + [INFO] Updated RouteManager with 0 routes  + HttpRouter initialized with 0 routes (0 unique hosts) + [INFO] HttpRouter initialized with 0 routes (0 unique hosts)  + HttpRouter initialized with 0 routes (0 unique hosts) + [INFO] HttpRouter initialized with 0 routes (0 unique hosts)  + [INFO] Route configuration updated with 0 routes  + [WARN] updateRoutes is deprecated - use SmartCertManager instead  + [INFO] WebSocket handler initialized  + [INFO] HttpProxy started on port 8845  +   info:  SmartProxy -> OK: Now listening on port 8443 +   info:  Using top-level ACME configuration with email: test@test.local +   info:  Starting certificate provisioning now that ports are ready +  debug  MetricsCollector started +   info:  SmartProxy shutting down... +   info:  Certificate manager stopped +   info:  NFTablesManager stopped +  debug  Port 8443 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8443 +   info:  All servers closed. Cleaning up active connections... + [INFO] Stopping HttpProxy server  + [INFO] Closing 0 WebSocket connections  + [INFO] Function cache cleared  + [INFO] HttpProxy server stopped successfully  +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… should defer certificate provisioning until after ports are listening (10ms) + Test starting: should have ACME challenge route ready before certificate provisioning +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +   WARN ->  1 configuration warnings found +   WARN ->  Port 8080 is not configured for any routes but is needed for ACME challenges. Add a route listening on port 8080 or ensure it's accessible for HTTP-01 challenges. +  debug  Port 8443 is used by 1 routes: test-route +   info:  SmartProxy starting with 1 ports: 8443 + [INFO] Route manager configured with 0 routes across 0 ports  + [INFO] Updated RouteManager with 0 routes  + [INFO] Loaded default certificates from filesystem (sync - deprecated)  + Initialized HttpProxy on port 8846 + [INFO] Updating route configurations (0 routes)  + [INFO] Route manager configured with 0 routes across 0 ports  + [INFO] Updated RouteManager with 0 routes  + HttpRouter initialized with 0 routes (0 unique hosts) + [INFO] HttpRouter initialized with 0 routes (0 unique hosts)  + HttpRouter initialized with 0 routes (0 unique hosts) + [INFO] HttpRouter initialized with 0 routes (0 unique hosts)  + [INFO] Route configuration updated with 0 routes  + [WARN] CertificateManager is deprecated - use SmartCertManager instead  + [WARN] updateRoutes is deprecated - use SmartCertManager instead  + [INFO] WebSocket handler initialized  + [INFO] HttpProxy started on port 8846  +   info:  SmartProxy -> OK: Now listening on port 8443 +   info:  Using top-level ACME configuration with email: test@test.local +   info:  Starting certificate provisioning now that ports are ready +  debug  MetricsCollector started +   info:  SmartProxy shutting down... +   info:  Certificate manager stopped +   info:  NFTablesManager stopped +  debug  Port 8443 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8443 +   info:  All servers closed. Cleaning up active connections... + [INFO] Stopping HttpProxy server  + [INFO] Closing 0 WebSocket connections  + [INFO] Function cache cleared  + [INFO] HttpProxy server stopped successfully  +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… should have ACME challenge route ready before certificate provisioning (103ms) + Summary: 2/2 PASSED in 2.4s + +▢️ test/test.certificate-acme-update.ts (18/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: SmartCertManager should call getCertificateForDomain with wildcard option + Testing SmartCertManager with SmartAcme v8.0.0 API... + Domain: example.com, DNS-01: true, Should include wildcard: true + Domain: example.com, DNS-01: false, Should include wildcard: false + Domain: sub.example.com, DNS-01: true, Should include wildcard: true + Domain: sub.example.com, DNS-01: false, Should include wildcard: false + Domain: *.example.com, DNS-01: true, Should include wildcard: false + Domain: *.example.com, DNS-01: false, Should include wildcard: false + Domain: test, DNS-01: true, Should include wildcard: false + Domain: test, DNS-01: false, Should include wildcard: false + Domain: my.sub.example.com, DNS-01: true, Should include wildcard: true + Domain: my.sub.example.com, DNS-01: false, Should include wildcard: false + All wildcard logic tests passed! + βœ… SmartCertManager should call getCertificateForDomain with wildcard option (1ms) + Summary: 1/1 PASSED in 2.3s + +▢️ test/test.certificate-provision.ts (19/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: SmartProxy should support custom certificate provision function +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes + βœ… SmartProxy should support custom certificate provision function (2ms) + Test starting: Custom certificate provision function should be called +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +   WARN ->  1 configuration warnings found +   WARN ->  Port 9080 is not configured for any routes but is needed for ACME challenges. Add a route listening on port 9080 or ensure it's accessible for HTTP-01 challenges. +  debug  Port 9443 is used by 1 routes: custom-cert-route +   info:  SmartProxy starting with 1 ports: 9443 +   info:  SmartProxy -> OK: Now listening on port 9443 +   info:  Using top-level ACME configuration with email: test@example.com +  debug  Route update callback set successfully + ❌ Custom certificate provision function should be called (0ms) + ⟦TSTEST:META:{"time":1375,"retry":0,"error":{"message":"Error validating contact(s) :: contact email has forbidden domain \"example.com\"","stack":"Error: Error validating contact(s) :: contact email has forbidden domain \"example.com\"\n at AcmeApi.apiRequest (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:53:19)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async AcmeApi.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:99:22)\n at async AcmeClient.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/client.js:180:26)\n at async SmartAcme.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartacme@8.0.0_@aws-sdk+credential-providers@3.798.0_socks@2.8.4/node_modules/@push.rocks/smartacme/ts/smartacme.classes.smartacme.ts:142:5)\n at async SmartCertManager.initialize (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/certificate-manager.ts:153:7)\n at async SmartProxy.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:256:5)\n at async SmartProxy.testProxy2.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:129:25)\n at async SmartProxy.initializeCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:313:24)\n at async SmartProxy.start (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:386:5)"}}⟧ + ⟦TSTEST:ERROR⟧ + { + "testNumber": 2, + "error": { + "message": "Error validating contact(s) :: contact email has forbidden domain \"example.com\"", + "stack": "Error: Error validating contact(s) :: contact email has forbidden domain \"example.com\"\n at AcmeApi.apiRequest (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:53:19)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async AcmeApi.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:99:22)\n at async AcmeClient.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/client.js:180:26)\n at async SmartAcme.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartacme@8.0.0_@aws-sdk+credential-providers@3.798.0_socks@2.8.4/node_modules/@push.rocks/smartacme/ts/smartacme.classes.smartacme.ts:142:5)\n at async SmartCertManager.initialize (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/certificate-manager.ts:153:7)\n at async SmartProxy.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:256:5)\n at async SmartProxy.testProxy2.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:129:25)\n at async SmartProxy.initializeCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:313:24)\n at async SmartProxy.start (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:386:5)" + } + } + Error details: + Error: Error validating contact(s) :: contact email has forbidden domain "example.com" + at AcmeApi.apiRequest (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:53:19) + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) + at async AcmeApi.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:99:22) + at async AcmeClient.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/client.js:180:26) + at async SmartAcme.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartacme@8.0.0_@aws-sdk+credential-providers@3.798.0_socks@2.8.4/node_modules/@push.rocks/smartacme/ts/smartacme.classes.smartacme.ts:142:5) + at async SmartCertManager.initialize (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/certificate-manager.ts:153:7) + at async SmartProxy.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:256:5) + at async SmartProxy.testProxy2.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:129:25) + at async SmartProxy.initializeCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:313:24) + at async SmartProxy.start (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:386:5) + Error: Error validating contact(s) :: contact email has forbidden domain "example.com" + at AcmeApi.apiRequest (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:53:19) + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) + at async AcmeApi.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:99:22) + at async AcmeClient.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/client.js:180:26) + at async SmartAcme.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartacme@8.0.0_@aws-sdk+credential-providers@3.798.0_socks@2.8.4/node_modules/@push.rocks/smartacme/ts/smartacme.classes.smartacme.ts:142:5) + at async SmartCertManager.initialize (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/certificate-manager.ts:153:7) + at async SmartProxy.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:256:5) + at async SmartProxy.testProxy2.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:129:25) + at async SmartProxy.initializeCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:313:24) + at async SmartProxy.start (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:386:5) + Test starting: Should fallback to ACME when custom provision fails +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +   WARN ->  1 configuration warnings found +   WARN ->  Port 9080 is not configured for any routes but is needed for ACME challenges. Add a route listening on port 9080 or ensure it's accessible for HTTP-01 challenges. +  debug  Port 9444 is used by 1 routes: fallback-route +   info:  SmartProxy starting with 1 ports: 9444 +   info:  SmartProxy -> OK: Now listening on port 9444 +   info:  Using top-level ACME configuration with email: test@example.com +  debug  Route update callback set successfully + ❌ Should fallback to ACME when custom provision fails (0ms) + ⟦TSTEST:META:{"time":1092,"retry":0,"error":{"message":"Error validating contact(s) :: contact email has forbidden domain \"example.com\"","stack":"Error: Error validating contact(s) :: contact email has forbidden domain \"example.com\"\n at AcmeApi.apiRequest (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:53:19)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async AcmeApi.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:99:22)\n at async AcmeClient.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/client.js:180:26)\n at async SmartAcme.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartacme@8.0.0_@aws-sdk+credential-providers@3.798.0_socks@2.8.4/node_modules/@push.rocks/smartacme/ts/smartacme.classes.smartacme.ts:142:5)\n at async SmartCertManager.initialize (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/certificate-manager.ts:153:7)\n at async SmartProxy.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:256:5)\n at async SmartProxy.testProxy3.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:191:25)\n at async SmartProxy.initializeCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:313:24)\n at async SmartProxy.start (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:386:5)"}}⟧ + ⟦TSTEST:ERROR⟧ + { + "testNumber": 3, + "error": { + "message": "Error validating contact(s) :: contact email has forbidden domain \"example.com\"", + "stack": "Error: Error validating contact(s) :: contact email has forbidden domain \"example.com\"\n at AcmeApi.apiRequest (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:53:19)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async AcmeApi.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:99:22)\n at async AcmeClient.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/client.js:180:26)\n at async SmartAcme.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartacme@8.0.0_@aws-sdk+credential-providers@3.798.0_socks@2.8.4/node_modules/@push.rocks/smartacme/ts/smartacme.classes.smartacme.ts:142:5)\n at async SmartCertManager.initialize (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/certificate-manager.ts:153:7)\n at async SmartProxy.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:256:5)\n at async SmartProxy.testProxy3.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:191:25)\n at async SmartProxy.initializeCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:313:24)\n at async SmartProxy.start (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:386:5)" + } + } + Error details: + Error: Error validating contact(s) :: contact email has forbidden domain "example.com" + at AcmeApi.apiRequest (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:53:19) + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) + at async AcmeApi.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:99:22) + at async AcmeClient.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/client.js:180:26) + at async SmartAcme.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartacme@8.0.0_@aws-sdk+credential-providers@3.798.0_socks@2.8.4/node_modules/@push.rocks/smartacme/ts/smartacme.classes.smartacme.ts:142:5) + at async SmartCertManager.initialize (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/certificate-manager.ts:153:7) + at async SmartProxy.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:256:5) + at async SmartProxy.testProxy3.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:191:25) + at async SmartProxy.initializeCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:313:24) + at async SmartProxy.start (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:386:5) + Error: Error validating contact(s) :: contact email has forbidden domain "example.com" + at AcmeApi.apiRequest (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:53:19) + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) + at async AcmeApi.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:99:22) + at async AcmeClient.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/client.js:180:26) + at async SmartAcme.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartacme@8.0.0_@aws-sdk+credential-providers@3.798.0_socks@2.8.4/node_modules/@push.rocks/smartacme/ts/smartacme.classes.smartacme.ts:142:5) + at async SmartCertManager.initialize (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/certificate-manager.ts:153:7) + at async SmartProxy.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:256:5) + at async SmartProxy.testProxy3.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:191:25) + at async SmartProxy.initializeCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:313:24) + at async SmartProxy.start (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:386:5) + Test starting: Should not fallback when certProvisionFallbackToAcme is false +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +   WARN ->  2 configuration warnings found +   WARN ->  Routes with certificate: "auto" require ACME email configuration. Add email to either top-level "acme" config or individual route's "tls.acme" config. +   WARN ->  Port 80 is not configured for any routes but is needed for ACME challenges. Add a route listening on port 80 or ensure it's accessible for HTTP-01 challenges. +  debug  Port 9445 is used by 1 routes: no-fallback-route +   info:  SmartProxy starting with 1 ports: 9445 +   info:  SmartProxy -> OK: Now listening on port 9445 + ❌ Should not fallback when certProvisionFallbackToAcme is false (0ms) + ⟦TSTEST:META:{"time":1,"retry":0,"error":{"message":"Expected value to be true","stack":"Error: Expected value to be true\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at BooleanMatchers.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/boolean.ts:11:27)\n at Proxy.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:337:43)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:273:23)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:20)\n at async TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:179:13)"}}⟧ + ⟦TSTEST:ERROR⟧ + { + "testNumber": 4, + "error": { + "message": "Expected value to be true", + "stack": "Error: Expected value to be true\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at BooleanMatchers.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/boolean.ts:11:27)\n at Proxy.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:337:43)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:273:23)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:20)\n at async TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:179:13)" + } + } + Error details: + Error: Expected value to be true + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at BooleanMatchers.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/boolean.ts:11:27) + at Proxy.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:337:43) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:273:23) + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) + at async TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:20) + at async TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:179:13) + Error: Expected value to be true + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at BooleanMatchers.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/boolean.ts:11:27) + at Proxy.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:337:43) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:273:23) + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) + at async TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:20) + at async TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:179:13) + Test starting: Should return http01 for unknown domains +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +   WARN ->  1 configuration warnings found +   WARN ->  Port 9081 is not configured for any routes but is needed for ACME challenges. Add a route listening on port 9081 or ensure it's accessible for HTTP-01 challenges. +  debug  Port 9446 is used by 1 routes: unknown-domain-route +   info:  SmartProxy starting with 1 ports: 9446 +   info:  SmartProxy -> OK: Now listening on port 9446 +   info:  Using top-level ACME configuration with email: test@example.com +  debug  Route update callback set successfully + ❌ Should return http01 for unknown domains (0ms) + ⟦TSTEST:META:{"time":963,"retry":0,"error":{"message":"Error validating contact(s) :: contact email has forbidden domain \"example.com\"","stack":"Error: Error validating contact(s) :: contact email has forbidden domain \"example.com\"\n at AcmeApi.apiRequest (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:53:19)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async AcmeApi.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:99:22)\n at async AcmeClient.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/client.js:180:26)\n at async SmartAcme.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartacme@8.0.0_@aws-sdk+credential-providers@3.798.0_socks@2.8.4/node_modules/@push.rocks/smartacme/ts/smartacme.classes.smartacme.ts:142:5)\n at async SmartCertManager.initialize (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/certificate-manager.ts:153:7)\n at async SmartProxy.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:256:5)\n at async SmartProxy.testProxy5.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:329:25)\n at async SmartProxy.initializeCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:313:24)\n at async SmartProxy.start (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:386:5)"}}⟧ + ⟦TSTEST:ERROR⟧ + { + "testNumber": 5, + "error": { + "message": "Error validating contact(s) :: contact email has forbidden domain \"example.com\"", + "stack": "Error: Error validating contact(s) :: contact email has forbidden domain \"example.com\"\n at AcmeApi.apiRequest (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:53:19)\n at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n at async AcmeApi.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:99:22)\n at async AcmeClient.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/client.js:180:26)\n at async SmartAcme.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartacme@8.0.0_@aws-sdk+credential-providers@3.798.0_socks@2.8.4/node_modules/@push.rocks/smartacme/ts/smartacme.classes.smartacme.ts:142:5)\n at async SmartCertManager.initialize (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/certificate-manager.ts:153:7)\n at async SmartProxy.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:256:5)\n at async SmartProxy.testProxy5.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:329:25)\n at async SmartProxy.initializeCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:313:24)\n at async SmartProxy.start (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:386:5)" + } + } + Error details: + Error: Error validating contact(s) :: contact email has forbidden domain "example.com" + at AcmeApi.apiRequest (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:53:19) + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) + at async AcmeApi.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:99:22) + at async AcmeClient.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/client.js:180:26) + at async SmartAcme.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartacme@8.0.0_@aws-sdk+credential-providers@3.798.0_socks@2.8.4/node_modules/@push.rocks/smartacme/ts/smartacme.classes.smartacme.ts:142:5) + at async SmartCertManager.initialize (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/certificate-manager.ts:153:7) + at async SmartProxy.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:256:5) + at async SmartProxy.testProxy5.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:329:25) + at async SmartProxy.initializeCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:313:24) + at async SmartProxy.start (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:386:5) + Error: Error validating contact(s) :: contact email has forbidden domain "example.com" + at AcmeApi.apiRequest (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:53:19) + at process.processTicksAndRejections (node:internal/process/task_queues:105:5) + at async AcmeApi.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/api.js:99:22) + at async AcmeClient.createAccount (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/acme-client@5.4.0/node_modules/acme-client/src/client.js:180:26) + at async SmartAcme.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartacme@8.0.0_@aws-sdk+credential-providers@3.798.0_socks@2.8.4/node_modules/@push.rocks/smartacme/ts/smartacme.classes.smartacme.ts:142:5) + at async SmartCertManager.initialize (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/certificate-manager.ts:153:7) + at async SmartProxy.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:256:5) + at async SmartProxy.testProxy5.createCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/test/test.certificate-provision.ts:329:25) + at async SmartProxy.initializeCertificateManager (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:313:24) + at async SmartProxy.start (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/smart-proxy.ts:386:5) + Test starting: cleanup +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… cleanup (1ms) + Test 2 failed with status error: + || Custom certificate provision function should be called + || for more information please take a look the logs above + Test 3 failed with status error: + || Should fallback to ACME when custom provision fails + || for more information please take a look the logs above + Test 4 failed with status error: + || Should not fallback when certProvisionFallbackToAcme is false + || for more information please take a look the logs above + Test 5 failed with status error: + || Should return http01 for unknown domains + || for more information please take a look the logs above +Running tree kill with SIGTERM on process 831913 + ❌ Test file timeout (60000ms) + Error: Test file exceeded timeout of 60 seconds + Error details: + Test execution was terminated after 60 seconds +Running tree kill with SIGKILL on process 831913 + +⚠️ Error + Only 7 out of 6 completed! + +⚠️ Error + The amount of received tests and expectedTests is unequal! Therefore the testfile failed + Summary: 2 passed, 5 failed of 7 tests in 60.1s + +⚠️ Error + Only 7 out of 6 completed! + +⚠️ Error + The amount of received tests and expectedTests is unequal! Therefore the testfile failed + Summary: 2 passed, 5 failed of 7 tests in 60.1s + +▢️ test/test.certificate-provisioning.ts (20/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes + Test starting: should provision certificate automatically +   WARN ->  1 configuration warnings found +   WARN ->  Port 9080 is not configured for any routes but is needed for ACME challenges. Add a route listening on port 9080 or ensure it's accessible for HTTP-01 challenges. +  debug  Port 9443 is used by 1 routes: test-route +   info:  SmartProxy starting with 1 ports: 9443 +   info:  SmartProxy -> OK: Now listening on port 9443 +   info:  Using route-level ACME configuration from route 'test-route' with email: test@test.local +   info:  Starting certificate provisioning now that ports are ready +  debug  MetricsCollector started +   info:  SmartProxy shutting down... +   info:  Certificate manager stopped +   info:  NFTablesManager stopped +  debug  Port 9443 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 9443 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… should provision certificate automatically (4ms) + Test starting: should handle static certificates +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 9444 is used by 1 routes: static-route +   info:  SmartProxy starting with 1 ports: 9444 +   info:  SmartProxy -> OK: Now listening on port 9444 +  debug  Route update callback set successfully +   info:  Certificate manager initialized. Deferring certificate provisioning until after ports are listening. +   info:  Starting certificate provisioning now that ports are ready +   WARN ->  HttpProxy not set, cannot apply certificate for domain static.example.com +   info:  Successfully loaded static certificate for static.example.com +  debug  MetricsCollector started +   info:  SmartProxy shutting down... +   info:  Certificate manager stopped +   info:  NFTablesManager stopped +  debug  Port 9444 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 9444 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… should handle static certificates (4ms) + Test starting: should handle ACME challenge routes +   info:  Route manager configured with 2 routes across 2 ports +   info:  Updated RouteManager with 2 routes +  debug  Port 9445 is used by 1 routes: auto-cert-route +  debug  Port 9081 is used by 1 routes: port-9081-route +   info:  SmartProxy starting with 2 ports: 9445, 9081 +   info:  SmartProxy -> OK: Now listening on port 9445 +   info:  SmartProxy -> OK: Now listening on port 9081 +   info:  Using route-level ACME configuration from route 'auto-cert-route' with email: acme@test.local +   info:  Starting certificate provisioning now that ports are ready +  debug  MetricsCollector started +   info:  SmartProxy shutting down... +   info:  Certificate manager stopped +   info:  NFTablesManager stopped +  debug  Port 9445 reference count decreased to 0 +  debug  Port 9081 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 9445 +   info:  SmartProxy -> Stopped listening on port 9081 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… should handle ACME challenge routes (1ms) + Test starting: should renew certificates +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +   WARN ->  1 configuration warnings found +   WARN ->  Port 9082 is not configured for any routes but is needed for ACME challenges. Add a route listening on port 9082 or ensure it's accessible for HTTP-01 challenges. +  debug  Port 9446 is used by 1 routes: renew-route +   info:  SmartProxy starting with 1 ports: 9446 +   info:  SmartProxy -> OK: Now listening on port 9446 +   info:  Using route-level ACME configuration from route 'renew-route' with email: renew@test.local +   info:  Starting certificate provisioning now that ports are ready +  debug  MetricsCollector started +   info:  SmartProxy shutting down... +   info:  Certificate manager stopped +   info:  NFTablesManager stopped +  debug  Port 9446 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 9446 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… should renew certificates (1ms) + Summary: 4/4 PASSED in 2.3s + +▢️ test/test.certificate-simple.ts (21/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: should create SmartProxy with certificate routes +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes + βœ… should create SmartProxy with certificate routes (2ms) + Test starting: should handle socket handler route type +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes + βœ… should handle socket handler route type (0ms) + Summary: 2/2 PASSED in 2.3s + +▢️ test/test.cleanup-queue-bug.node.ts (22/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: cleanup queue bug - verify queue processing handles more than batch size +  + === Cleanup Queue Bug Test === + Purpose: Verify that the cleanup queue correctly processes all connections + even when there are more than the batch size (100) +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 8588 is used by 1 routes: test-route +   info:  SmartProxy starting with 1 ports: 8588 +   info:  SmartProxy -> OK: Now listening on port 8588 +   info:  No routes require certificate management +  debug  MetricsCollector started + βœ“ Proxy started on port 8588 +  + --- Creating 150 mock connections --- + Created 150 mock connections +  + --- Queueing all connections for cleanup --- +   info:  Cleaned up 50 connections +   info:  Cleaned up 50 connections +   info:  [SUMMARY] 50 connections terminated in 0s +   info:  [SUMMARY] 50 connections terminated in 0s +   info:  Cleaned up 50 connections + Cleanup queue size after queueing: 50 + Active connections after initial batch: 50 +  + --- Waiting for remaining cleanup batches to process --- +   info:  [SUMMARY] 50 connections terminated in 0s + Active connections: 0, Queue size: 0 + All cleanup completed in 100ms +  + Final connection count: 0 + Final cleanup queue size: 0 + Termination stats: { incoming: { test_cleanup: 150 }, outgoing: {} } +  + --- Stopping proxy --- +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8588 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8588 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. +  + βœ“ Test complete: Cleanup queue now correctly processes all connections + βœ… cleanup queue bug - verify queue processing handles more than batch size (111ms) + Summary: 1/1 PASSED in 2.5s + +▢️ test/test.connect-disconnect-cleanup.node.ts (23/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: should handle clients that connect and immediately disconnect without sending data +  + === Testing Connect-Disconnect Cleanup === +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 8560 is used by 1 routes: test-route +   info:  SmartProxy starting with 1 ports: 8560 +   info:  SmartProxy -> OK: Now listening on port 8560 +   info:  No routes require certificate management +  debug  MetricsCollector started + βœ“ Proxy started on port 8560 + Initial connection count: 0 +  + --- Test 1: Immediate disconnect --- +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 1 +  debug  Connection z4g8slckt7vtyuodqbii closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for z4g8slckt7vtyuodqbii +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 1 +  debug  Connection 7fx7llyal68bm7to9p86ej closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for 7fx7llyal68bm7to9p86ej +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 1 +  debug  Connection f1ziq2h21or2yp0u5v4ddm closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for f1ziq2h21or2yp0u5v4ddm +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 1 +  debug  Connection zukzivxcejd2t333sl0xt closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for zukzivxcejd2t333sl0xt +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 1 +  debug  Connection v43801kx99zqp24ok4tzi closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for v43801kx99zqp24ok4tzi + After 5 connect/disconnect cycles: 0 active connections +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 1 +  debug  Connection 9obb1kcen3z1immr11gz9 closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for 9obb1kcen3z1immr11gz9 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 1 +  debug  Connection ekriyzqdok8tcdzpt2ea1 closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for ekriyzqdok8tcdzpt2ea1 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 1 +  debug  Connection o7md8vzt7fez3a8jz53a closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for o7md8vzt7fez3a8jz53a +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 1 +  debug  Connection hben6esak3oxzttf8y37s closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for hben6esak3oxzttf8y37s +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 1 +  debug  Connection y9iq1yeg7vun2d8piu36j closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for y9iq1yeg7vun2d8piu36j + After 10 connect/disconnect cycles: 0 active connections + After immediate disconnect test: 0 active connections +  + --- Test 2: Delayed disconnect --- + During delayed disconnect test: 0 active connections +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 1 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 2 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for kfngu0xyiejc5krrakogw9 to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection kfngu0xyiejc5krrakogw9: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection kfngu0xyiejc5krrakogw9 closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 36ys39edifqz65pj2czir to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 36ys39edifqz65pj2czir: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 36ys39edifqz65pj2czir closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for u28bqn0f6akcvxj3kao3 to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection u28bqn0f6akcvxj3kao3: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection u28bqn0f6akcvxj3kao3 closed during immediate routing: immediate-route-client_closed + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 9jrlpx2i0z7pqht1nuevc to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 9jrlpx2i0z7pqht1nuevc: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 9jrlpx2i0z7pqht1nuevc closed during immediate routing: immediate-route-client_closed +   ERROR!  Connection setup error for fvsdatr60nj7gqyclah0h to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection fvsdatr60nj7gqyclah0h: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +  debug  Connection fvsdatr60nj7gqyclah0h closed during immediate routing: immediate-route-client_closed + After delayed disconnect test: 0 active connections +  + --- Test 3: Mixed disconnect patterns --- +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 1 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 2 +  debug  Connection jpe2u6zwa7rrkbdg9wac8k closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for jpe2u6zwa7rrkbdg9wac8k +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 2 +  debug  Connection skmr4n5dktqg8e0k9q8d closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for skmr4n5dktqg8e0k9q8d +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 2 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for ph3gosnyrvfrruh227o to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection ph3gosnyrvfrruh227o: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection jz3my9vq4skyvg3lbmxdk closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for jz3my9vq4skyvg3lbmxdk +  debug  Connection ph3gosnyrvfrruh227o closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 2 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 3ntc1ewmtshoeg2c7d74n to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 3ntc1ewmtshoeg2c7d74n: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 3ntc1ewmtshoeg2c7d74n closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 2e8c58q77imfckvw0hqcq to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 2e8c58q77imfckvw0hqcq: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection fjbx4c0duxitefvomsl0lf closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for fjbx4c0duxitefvomsl0lf +  debug  Connection 2e8c58q77imfckvw0hqcq closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 2 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 3 +   ERROR!  Connection setup error for vl6gtrry9hobgqqrlzcokr to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection vl6gtrry9hobgqqrlzcokr: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +  debug  Connection lo9in7x1bwfdaxqe52lf0p closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for lo9in7x1bwfdaxqe52lf0p +  debug  Connection vl6gtrry9hobgqqrlzcokr closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 2 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for v2w1xbhsa4sfhtqkfu3bd to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection v2w1xbhsa4sfhtqkfu3bd: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 0724p3xmk5mcquh3rm6zlre closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for 0724p3xmk5mcquh3rm6zlre +  debug  Connection v2w1xbhsa4sfhtqkfu3bd closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 2 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for s6m8rip71fbja60vbcfr7 to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection s6m8rip71fbja60vbcfr7: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 234angsfx56jtq7cnuvq7l closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for 234angsfx56jtq7cnuvq7l +  debug  Connection s6m8rip71fbja60vbcfr7 closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 2 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 35hof8ei6pzndz4r98hqc to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 35hof8ei6pzndz4r98hqc: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 1cx5822jzdh5kew1wpla8m closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for 1cx5822jzdh5kew1wpla8m +  debug  Connection 35hof8ei6pzndz4r98hqc closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 2 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for crrxjxn1e1qoz1ojdwhwj9 to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection crrxjxn1e1qoz1ojdwhwj9: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection cqvb8pv67tzldv8e1zu7 closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for cqvb8pv67tzldv8e1zu7 +  debug  Connection crrxjxn1e1qoz1ojdwhwj9 closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 2 +   info:  New connection from ::ffff:127.0.0.1 on port 8560. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for dg3k64rc6kkulpjqpkutom to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection dg3k64rc6kkulpjqpkutom: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +   ERROR!  Connection setup error for 26iizwpc0xder7cv3h20t to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 26iizwpc0xder7cv3h20t: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +  debug  Connection 26iizwpc0xder7cv3h20t closed during immediate routing: immediate-route-client_closed +  debug  Connection dg3k64rc6kkulpjqpkutom closed during immediate routing: immediate-route-client_closed + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for ihnsujrjrehna6zyvgkqs to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection ihnsujrjrehna6zyvgkqs: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection ihnsujrjrehna6zyvgkqs closed during immediate routing: immediate-route-client_closed + During mixed test: 0 active connections +  + Final connection count: 0 +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8560 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8560 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  [SUMMARY] 35 HttpProxy connections terminated in 3s +   info:  SmartProxy shutdown complete. + βœ“ Proxy stopped +  + Max connection count during immediate disconnect test: 0 +  + βœ… PASS: Connect-disconnect cleanup working correctly! + βœ… should handle clients that connect and immediately disconnect without sending data (2627ms) + Test starting: should handle clients that error during connection +  + === Testing Connection Error Cleanup === +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 8561 is used by 1 routes: test-route +   info:  SmartProxy starting with 1 ports: 8561 +   info:  SmartProxy -> OK: Now listening on port 8561 +   info:  No routes require certificate management +  debug  MetricsCollector started + βœ“ Proxy started on port 8561 + Initial connection count: 0 +   info:  New connection from ::ffff:127.0.0.1 on port 8561. Active connections: 1 +   info:  New connection from ::ffff:127.0.0.1 on port 8561. Active connections: 2 + βœ“ All error connections completed +   info:  New connection from ::ffff:127.0.0.1 on port 8561. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for wcpvigag82dadhm5ig21r to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection wcpvigag82dadhm5ig21r: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection wcpvigag82dadhm5ig21r closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8561. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for if9c8blul4bndfh8zoq0a to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection if9c8blul4bndfh8zoq0a: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection if9c8blul4bndfh8zoq0a closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8561. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for unnow458g1bm3793nte9r to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection unnow458g1bm3793nte9r: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection unnow458g1bm3793nte9r closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8561. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for ufpwhmocpxi6unyfljw229 to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection ufpwhmocpxi6unyfljw229: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection ufpwhmocpxi6unyfljw229 closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8561. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for o77vhbbwc8s4edyxazh9xz to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection o77vhbbwc8s4edyxazh9xz: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection o77vhbbwc8s4edyxazh9xz closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8561. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 57bi5afer5o0uj5ms0tu71h to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 57bi5afer5o0uj5ms0tu71h: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 57bi5afer5o0uj5ms0tu71h closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8561. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for ogu3nplgadgaaa0knvlv3e to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection ogu3nplgadgaaa0knvlv3e: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection ogu3nplgadgaaa0knvlv3e closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8561. Active connections: 3 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 3bf3u5awhvgwlappda8mg to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 3bf3u5awhvgwlappda8mg: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 3bf3u5awhvgwlappda8mg closed during immediate routing: immediate-route-client_closed + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 2fc87e59pmj563r5jv5wa to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 2fc87e59pmj563r5jv5wa: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 2fc87e59pmj563r5jv5wa closed during immediate routing: immediate-route-client_closed +   ERROR!  Connection setup error for 8jvy2k1kyo29pj8630i0ag to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection 8jvy2k1kyo29pj8630i0ag: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 8jvy2k1kyo29pj8630i0ag closed during immediate routing: immediate-route-client_closed + Final connection count: 0 +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8561 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8561 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  [SUMMARY] 10 HttpProxy connections terminated in 0s +   info:  SmartProxy shutdown complete. + βœ“ Proxy stopped +  + βœ… PASS: Connection error cleanup working correctly! + βœ… should handle clients that error during connection (509ms) + Summary: 2/2 PASSED in 33.9s + +▢️ test/test.connection-cleanup-comprehensive.node.ts (24/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: comprehensive connection cleanup test - all scenarios +  + === Comprehensive Connection Cleanup Test === +   info:  Route manager configured with 2 routes across 2 ports +   info:  Updated RouteManager with 2 routes +  debug  Port 8570 is used by 1 routes: non-tls-route +  debug  Port 8571 is used by 1 routes: tls-route +   info:  SmartProxy starting with 2 ports: 8570, 8571 +   info:  SmartProxy -> OK: Now listening on port 8570 +   info:  SmartProxy -> OK: Now listening on port 8571 +   info:  No routes require certificate management +  debug  MetricsCollector started + βœ“ Proxy started on ports 8570 (non-TLS) and 8571 (TLS) + Initial connection count: 0 +  + --- Test 1: Rapid ECONNREFUSED retries --- +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for zf6f23nln8evownmuo2k1g to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection zf6f23nln8evownmuo2k1g: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection zf6f23nln8evownmuo2k1g closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for c6qak6js5pogf1v4amna to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection c6qak6js5pogf1v4amna: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection c6qak6js5pogf1v4amna closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for msioo6bzopvcnbnvpm54p to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection msioo6bzopvcnbnvpm54p: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection msioo6bzopvcnbnvpm54p closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 7olpugixxsrw91hetit77j to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 7olpugixxsrw91hetit77j: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 7olpugixxsrw91hetit77j closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for huul5v518v6gzkzo7pxk5p to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection huul5v518v6gzkzo7pxk5p: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection huul5v518v6gzkzo7pxk5p closed during immediate routing: immediate-route-client_closed + After 5 ECONNREFUSED retries: 0 active connections +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for z5ieea1klitshovosek1k to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection z5ieea1klitshovosek1k: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection z5ieea1klitshovosek1k closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for fra671xpfuew0se7nanab to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection fra671xpfuew0se7nanab: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection fra671xpfuew0se7nanab closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 6xc11p6ix6amh852lhqbn to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 6xc11p6ix6amh852lhqbn: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 6xc11p6ix6amh852lhqbn closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for vkighf9nmdextd9gajxrc to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection vkighf9nmdextd9gajxrc: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection vkighf9nmdextd9gajxrc closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for buri0uelsbwmk7ywq6xh to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection buri0uelsbwmk7ywq6xh: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection buri0uelsbwmk7ywq6xh closed during immediate routing: immediate-route-client_closed + After 10 ECONNREFUSED retries: 0 active connections +  + --- Test 2: Connect without sending data --- +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 +  debug  Connection pcktfu7jn3khmjrewx9eir closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for pcktfu7jn3khmjrewx9eir +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 +  debug  Connection nd059veyl1jjad5qnwx4e closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for nd059veyl1jjad5qnwx4e +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 +  debug  Connection q9bvrdsedycgeckjm6h08 closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for q9bvrdsedycgeckjm6h08 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 +  debug  Connection k5r8box85qfogjagfcnl5s closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for k5r8box85qfogjagfcnl5s +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 +  debug  Connection gor7e04mnput16sizffvl closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for gor7e04mnput16sizffvl +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 +  debug  Connection zkeaje6668pnf6katww4bl closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for zkeaje6668pnf6katww4bl +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 +  debug  Connection msl8etyyajfl60cuyqo59 closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for msl8etyyajfl60cuyqo59 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 +  debug  Connection 5ikimuh068wmj04cuwzxnh closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for 5ikimuh068wmj04cuwzxnh +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 +  debug  Connection aqkayqlsyorlqvrwhlvp closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for aqkayqlsyorlqvrwhlvp +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 +  debug  Connection s2tozbqrogfz7aijs8vl6s closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for s2tozbqrogfz7aijs8vl6s + After connect-without-data test: 0 active connections +  + --- Test 3: TLS early disconnect --- +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 1 +  debug  Connection s1uagbohwgzwhqbep163 ended before sending initial data +   WARN ->  Connection s1uagbohwgzwhqbep163 closed before sending initial data +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 1 +  debug  Connection ttca3tp7gi32eje3eiu4 ended before sending initial data +   WARN ->  Connection ttca3tp7gi32eje3eiu4 closed before sending initial data +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 1 +  debug  Connection jl7jlfcvk5b8ogys1iupu ended before sending initial data +   WARN ->  Connection jl7jlfcvk5b8ogys1iupu closed before sending initial data +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 1 +  debug  Connection l0xx413gpheis6988yode ended before sending initial data +   WARN ->  Connection l0xx413gpheis6988yode closed before sending initial data +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 1 +  debug  Connection iz2cmbrr6j01hlfh0clbjj ended before sending initial data +   WARN ->  Connection iz2cmbrr6j01hlfh0clbjj closed before sending initial data +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 1 +  debug  Connection um5hc44ym8hedz6umy5qfk ended before sending initial data +   WARN ->  Connection um5hc44ym8hedz6umy5qfk closed before sending initial data +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 1 +  debug  Connection pg1i86etdhyyognu1pytq ended before sending initial data +   WARN ->  Connection pg1i86etdhyyognu1pytq closed before sending initial data +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 1 +  debug  Connection 568pppo5to7zkkrfat9u2f ended before sending initial data +   WARN ->  Connection 568pppo5to7zkkrfat9u2f closed before sending initial data +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 1 +  debug  Connection st1nzucdd3skx500qdrul ended before sending initial data +   WARN ->  Connection st1nzucdd3skx500qdrul closed before sending initial data +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 1 +  debug  Connection 7xkb7ynlc7g06vxkck5d3x8 ended before sending initial data +   WARN ->  Connection 7xkb7ynlc7g06vxkck5d3x8 closed before sending initial data + After TLS early disconnect test: 0 active connections +  + --- Test 4: Mixed chaos pattern --- +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 +  debug  Connection l5f47791p0g8chtide7ux2 closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for l5f47791p0g8chtide7ux2 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 1 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 2 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 3 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 4 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 5 +  debug  Connection pc0ke27lds2ryvh19nsok ended before sending initial data + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for hvd23lveq3ru5t0a0te38 to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection hvd23lveq3ru5t0a0te38: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +   ERROR!  Connection setup error for 8t5blofd7sp0j97z8euvj7r to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 8t5blofd7sp0j97z8euvj7r: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   WARN ->  Connection pc0ke27lds2ryvh19nsok closed before sending initial data +  debug  Connection 8t5blofd7sp0j97z8euvj7r closed during immediate routing: immediate-route-client_closed + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for b46chasw9pcntv4v39hkp to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection b46chasw9pcntv4v39hkp: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +   ERROR!  Connection setup error for bzxhmmcb9pqrhbyul1bd8 to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection bzxhmmcb9pqrhbyul1bd8: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection b46chasw9pcntv4v39hkp closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 1 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 2 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 3 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 4 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 5 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 8z65n3wlhhaqx4jtb4jxsg to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 8z65n3wlhhaqx4jtb4jxsg: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 8z65n3wlhhaqx4jtb4jxsg closed during immediate routing: immediate-route-client_closed + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for x9v1bkf1r6k36lwrzcdwnz to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection x9v1bkf1r6k36lwrzcdwnz: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 59j3o76c3at19p6v224er6 closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for 59j3o76c3at19p6v224er6 +  debug  Connection x9v1bkf1r6k36lwrzcdwnz closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 3 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 4 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 5 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 6 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 7 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for a1kvb83a4dbrt1q5zubuw to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection a1kvb83a4dbrt1q5zubuw: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 98e5dr4hjgtf37p95j5zcl ended before sending initial data +   WARN ->  Connection 98e5dr4hjgtf37p95j5zcl closed before sending initial data +  debug  Connection a1kvb83a4dbrt1q5zubuw closed during immediate routing: immediate-route-client_closed + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for j93pjbypycxr2c13vawc to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection j93pjbypycxr2c13vawc: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +   ERROR!  Connection setup error for chlcux73fcits9x1ddxbg to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection chlcux73fcits9x1ddxbg: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection chlcux73fcits9x1ddxbg closed during immediate routing: immediate-route-client_closed +   ERROR!  Connection setup error for dpurq2fol6gwu0el6obkec to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection dpurq2fol6gwu0el6obkec: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 3 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 4 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 5 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 6 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 7 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 9r7efkmf366mkcv2rmi2w to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 9r7efkmf366mkcv2rmi2w: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 9r7efkmf366mkcv2rmi2w closed during immediate routing: immediate-route-client_closed + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for o337cwrdg0pxh8n2emu4u to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection o337cwrdg0pxh8n2emu4u: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection u3cp5ya9d964zv4zu909a closed during immediate routing: immediate-route-client_closed +  debug  Destroying outgoing connection for u3cp5ya9d964zv4zu909a +  debug  Connection o337cwrdg0pxh8n2emu4u closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 5 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 6 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 7 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 8 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 9 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for o7uj8ag2w8olebkdlwygw to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection o7uj8ag2w8olebkdlwygw: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection o7uj8ag2w8olebkdlwygw closed during immediate routing: immediate-route-client_closed + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for g6itie3murvgxy1kt28qiq to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection g6itie3murvgxy1kt28qiq: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection gtizlh04w39j15vop7cju ended before sending initial data +   WARN ->  Connection gtizlh04w39j15vop7cju closed before sending initial data +   info:  [SUMMARY] 50 HttpProxy connections terminated in 1s +  debug  Connection g6itie3murvgxy1kt28qiq closed during immediate routing: immediate-route-client_closed +   ERROR!  Connection setup error for l2l5brkqaf3q21v4aww2h to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection l2l5brkqaf3q21v4aww2h: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for gcu0g564rz5rznhdyjt50i to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection gcu0g564rz5rznhdyjt50i: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 5 +   info:  New connection from ::ffff:127.0.0.1 on port 8570. Active connections: 6 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 7 +   info:  New connection from ::ffff:127.0.0.1 on port 8571. Active connections: 8 + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +   ERROR!  Connection setup error for 7dpd3osdzr5l37ynqa2m0o to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection 7dpd3osdzr5l37ynqa2m0o: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. +  debug  Connection 7dpd3osdzr5l37ynqa2m0o closed during immediate routing: immediate-route-client_closed +   ERROR!  Connection setup error for jy7uj3i4skevp71qswjlgf to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 (ECONNREFUSED) +   ERROR!  Connection jy7uj3i4skevp71qswjlgf: Target localhost:9999 refused connection. Check if the target service is running and listening on that port. + Socket connection error to localhost:9999: connect ECONNREFUSED 127.0.0.1:9999 +  debug  Connection jy7uj3i4skevp71qswjlgf closed during immediate routing: immediate-route-client_closed +  debug  Connection ozwwrsk6j5hb4pdsgz7f9e ended before sending initial data +   WARN ->  Connection ozwwrsk6j5hb4pdsgz7f9e closed before sending initial data +  debug  Connection wpro3jrix6tuyupb29j4 ended before sending initial data +   WARN ->  Connection wpro3jrix6tuyupb29j4 closed before sending initial data +  debug  Connection giss9kkg85syhf5ipnubbe ended before sending initial data +   WARN ->  Connection giss9kkg85syhf5ipnubbe closed before sending initial data +  debug  Connection heegnj1ldgej7jp6rdnbuj ended before sending initial data +   WARN ->  Connection heegnj1ldgej7jp6rdnbuj closed before sending initial data +  debug  Connection 20v5tvlfq85rm8j1t8urbe ended before sending initial data +   WARN ->  Connection 20v5tvlfq85rm8j1t8urbe closed before sending initial data + βœ“ Chaos test completed +  debug  Connection zj9rtxtlfj8gallvtwbiw ended before sending initial data +   WARN ->  Connection zj9rtxtlfj8gallvtwbiw closed before sending initial data + After chaos test: 0 active connections +  + --- Test 5: NFTables route cleanup --- +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 8572 is used by 1 routes: nftables-route +   info:  SmartProxy starting with 1 ports: 8572 + [2025-07-20T13:16:32.571Z] [WARN] Command failed (attempt 1/3): nft list tables ip {"error":"Command failed: nft list tables ip\nOperation not permitted (you must be root)\nnetlink: Error: cache initialization failed: Operation not permitted\n"} + [2025-07-20T13:16:33.578Z] [WARN] Command failed (attempt 2/3): nft list tables ip {"error":"Command failed: nft list tables ip\nOperation not permitted (you must be root)\nnetlink: Error: cache initialization failed: Operation not permitted\n"} + [2025-07-20T13:16:34.585Z] [WARN] Command failed (attempt 3/3): nft list tables ip {"error":"Command failed: nft list tables ip\nOperation not permitted (you must be root)\nnetlink: Error: cache initialization failed: Operation not permitted\n"} + [2025-07-20T13:16:34.585Z] [ERROR] Failed to set up tables and chains: Failed after 3 attempts: Command failed: nft list tables ip + Operation not permitted (you must be root) + netlink: Error: cache initialization failed: Operation not permitted +  + Failed to provision NFTables rules for route nftables-route: Failed to set up nftables tables and chains +   info:  SmartProxy -> OK: Now listening on port 8572 +   info:  No routes require certificate management +  debug  MetricsCollector started +   info:  New connection from ::ffff:127.0.0.1 on port 8572. Active connections: 1 +   info:  NFTables forwarding +  debug  Connection bhuhcgca0gsxbqi086lpr closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8572. Active connections: 1 +   info:  NFTables forwarding +  debug  Connection y4bm3bpcdhjli7ac9b7tn closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8572. Active connections: 1 +   info:  NFTables forwarding +  debug  Connection elz81dgwu2j9qlehyg495u closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8572. Active connections: 1 +   info:  NFTables forwarding +  debug  Connection phgzjmpiqtjyeg6d39aps closed during immediate routing: immediate-route-client_closed +   info:  New connection from ::ffff:127.0.0.1 on port 8572. Active connections: 1 +   info:  NFTables forwarding +  debug  Connection c6ftdqzrgkinnfqeiyp8dp closed during immediate routing: immediate-route-client_closed + NFTables connections after test: 0 +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8572 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8572 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  [SUMMARY] 15 HttpProxy connections terminated in 5s +   info:  SmartProxy shutdown complete. +  + Final connection count: 0 +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8570 reference count decreased to 0 +  debug  Port 8571 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8570 +   info:  SmartProxy -> Stopped listening on port 8571 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ“ Proxy stopped +  + βœ… PASS: Comprehensive connection cleanup test passed! + All connection scenarios properly cleaned up: + - ECONNREFUSED rapid retries + - Connect without sending data + - TLS early disconnect + - Mixed chaos patterns + - NFTables connections + βœ… comprehensive connection cleanup test - all scenarios (5729ms) + [DEPRECATION WARNING] executeWithRetrySync blocks the event loop and should not be used. Consider using the async executeWithRetry method instead. + Operation not permitted (you must be root) + netlink: Error: cache initialization failed: Operation not permitted + [2025-07-20T13:17:01.043Z] [WARN] Command failed (attempt 1/3): nft list tables ip {"error":"Command failed: nft list tables ip\nOperation not permitted (you must be root)\nnetlink: Error: cache initialization failed: Operation not permitted\n"} + Operation not permitted (you must be root) + netlink: Error: cache initialization failed: Operation not permitted + [2025-07-20T13:17:02.049Z] [WARN] Command failed (attempt 2/3): nft list tables ip {"error":"Command failed: nft list tables ip\nOperation not permitted (you must be root)\nnetlink: Error: cache initialization failed: Operation not permitted\n"} + Operation not permitted (you must be root) + netlink: Error: cache initialization failed: Operation not permitted + [2025-07-20T13:17:03.054Z] [WARN] Command failed (attempt 3/3): nft list tables ip {"error":"Command failed: nft list tables ip\nOperation not permitted (you must be root)\nnetlink: Error: cache initialization failed: Operation not permitted\n"} + [2025-07-20T13:17:03.054Z] [ERROR] Error cleaning up tables: Failed after 3 attempts: Command failed: nft list tables ip + Operation not permitted (you must be root) + netlink: Error: cache initialization failed: Operation not permitted +  + Summary: 1/1 PASSED in 35.5s + +▢️ test/test.connection-forwarding.ts (25/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: setup test servers + TCP test server listening on port 7001 + TLS test server listening on port 7002 + βœ… setup test servers (7ms) + Test starting: should forward TCP connections correctly +   info:  Route manager configured with 1 routes across 1 ports +   info:  Port 8080: 1 routes (TCP Forward Route) +   info:  Updated RouteManager with 1 routes +  debug  Port 8080 is used by 1 routes: TCP Forward Route +   info:  SmartProxy starting with 1 ports: 8080 +   info:  SmartProxy -> OK: Now listening on port 8080 +   info:  No routes require certificate management +  debug  MetricsCollector started +  debug  MetricsCollector: New connection recorded +   info:  New connection from ::ffff:127.0.0.1 on port 8080. Keep-Alive: Enabled. Active connections: 1 +   info:  Route matched +  debug  Checking HttpProxy forwarding: port=8080, useHttpProxy=undefined, isHttpProxyPort=undefined, hasHttpProxy=false +   info:  Using basic forwarding to 127.0.0.1:7001 for connection nvh865fr17km2lugzckwm +   info:  Setting up direct connection nvh865fr17km2lugzckwm to 127.0.0.1:7001 + Connected to proxy +   info:  Connection nvh865fr17km2lugzckwm established to target 127.0.0.1:7001 +   info:  Connection established: ::ffff:127.0.0.1 -> 127.0.0.1:7001 + Received: Connected to TCP test server + TCP Echo: Hello from client +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8080 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8080 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… should forward TCP connections correctly (12ms) + Test starting: should handle TLS passthrough correctly +   info:  Route manager configured with 1 routes across 1 ports +   info:  Port 8443: 1 routes (TLS Passthrough Route) +   info:  Updated RouteManager with 1 routes +  debug  Port 8443 is used by 1 routes: TLS Passthrough Route +   info:  SmartProxy starting with 1 ports: 8443 +   info:  SmartProxy -> OK: Now listening on port 8443 +   info:  No routes require certificate management +  debug  MetricsCollector started +  debug  Connection nvh865fr17km2lugzckwm closed during immediate routing: immediate-route-client_closed +  debug  MetricsCollector: New connection recorded +   info:  New connection from ::ffff:127.0.0.1 on port 8443. Keep-Alive: Enabled. Active connections: 1 +   info:  TLS connection with SNI +   info:  Route matched +   info:  Using TLS passthrough to 127.0.0.1:7002 for connection i25yix0vkufu0fkr8gr4tj +   info:  Setting up direct connection i25yix0vkufu0fkr8gr4tj to 127.0.0.1:7002 +   info:  Connection i25yix0vkufu0fkr8gr4tj established to target 127.0.0.1:7002 + [i25yix0vkufu0fkr8gr4tj] Forwarding 374 bytes of initial data to target +   info:  Connection established: ::ffff:127.0.0.1 -> 127.0.0.1:7002 (SNI: test.example.com) +   info:  TLS renegotiation handler installed for connection i25yix0vkufu0fkr8gr4tj with SNI test.example.com + Connected via TLS + TLS Received: Connected to TLS test server +  +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8443 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8443 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  [SUMMARY] 1 HttpProxy connections terminated in 0s +   info:  SmartProxy shutdown complete. + βœ… should handle TLS passthrough correctly (10ms) + Test starting: should handle SNI-based forwarding +   info:  Route manager configured with 2 routes across 1 ports +   info:  Port 8443: 2 routes (Domain A Route, Domain B Route) +   info:  Updated RouteManager with 2 routes +  debug  Port 8443 is used by 2 routes: Domain A Route, Domain B Route +   info:  SmartProxy starting with 1 ports: 8443 +   info:  SmartProxy -> OK: Now listening on port 8443 +   info:  No routes require certificate management +  debug  MetricsCollector started +  debug  MetricsCollector: New connection recorded +   info:  New connection from ::ffff:127.0.0.1 on port 8443. Keep-Alive: Enabled. Active connections: 1 +   info:  TLS connection with SNI +   info:  Route matched +   info:  Using TLS passthrough to 127.0.0.1:7002 for connection pz6gamc2wymn6s432i83z +   info:  Setting up direct connection pz6gamc2wymn6s432i83z to 127.0.0.1:7002 +   info:  Connection pz6gamc2wymn6s432i83z established to target 127.0.0.1:7002 + [pz6gamc2wymn6s432i83z] Forwarding 371 bytes of initial data to target +   info:  Connection established: ::ffff:127.0.0.1 -> 127.0.0.1:7002 (SNI: a.example.com) +   info:  TLS renegotiation handler installed for connection pz6gamc2wymn6s432i83z with SNI a.example.com + Connected to domain A + Domain A response: Connected to TLS test server +  +  debug  MetricsCollector: New connection recorded +   info:  New connection from ::ffff:127.0.0.1 on port 8443. Keep-Alive: Enabled. Active connections: 2 +   info:  TLS connection with SNI +   info:  Route matched +   info:  Using TLS passthrough to 127.0.0.1:7002 for connection crlvaparay7acwg2aghmsf +   info:  Setting up direct connection crlvaparay7acwg2aghmsf to 127.0.0.1:7002 +   info:  Connection crlvaparay7acwg2aghmsf established to target 127.0.0.1:7002 + [crlvaparay7acwg2aghmsf] Forwarding 371 bytes of initial data to target +   info:  Connection established: ::ffff:127.0.0.1 -> 127.0.0.1:7002 (SNI: b.example.com) +   info:  TLS renegotiation handler installed for connection crlvaparay7acwg2aghmsf with SNI b.example.com + Connected to domain B + Domain B response: Connected to TLS test server +  +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8443 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8443 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  [SUMMARY] 1 HttpProxy connections terminated in 0s +   info:  SmartProxy shutdown complete. + βœ… should handle SNI-based forwarding (10ms) + Test starting: cleanup + βœ… cleanup (0ms) + Summary: 5/5 PASSED in 2.3s + +▢️ test/test.connection-limits.node.ts (26/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: Setup test environment + [Test Server] Listening on localhost:5100 +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 5101 is used by 1 routes: test-route +   info:  SmartProxy starting with 1 ports: 5101 +   info:  SmartProxy -> OK: Now listening on port 5101 +   info:  No routes require certificate management +  debug  MetricsCollector started + βœ… Setup test environment (11ms) + Test starting: Per-IP connection limits +   info:  New connection from ::ffff:127.0.0.1 on port 5101. Active connections: 1 +   info:  New connection from ::ffff:127.0.0.1 on port 5101. Active connections: 2 +   info:  New connection from ::ffff:127.0.0.1 on port 5101. Active connections: 3 +   info:  Connection established: ::ffff:127.0.0.1 -> localhost:5100 + ❌ Per-IP connection limits (0ms) + ⟦TSTEST:META:{"time":8,"retry":0,"error":{"message":"Expected string to include \"ECONNRESET\"","stack":"Error: Expected string to include \"ECONNRESET\"\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at StringMatchers.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/string.ts:25:27)\n at Proxy.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:355:60)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.connection-limits.node.ts:125:25)\n at async TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:20)\n at async TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:179:13)\n at async Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:532:9)"}}⟧ + ⟦TSTEST:ERROR⟧ + { + "testNumber": 2, + "error": { + "message": "Expected string to include \"ECONNRESET\"", + "stack": "Error: Expected string to include \"ECONNRESET\"\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at StringMatchers.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/string.ts:25:27)\n at Proxy.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:355:60)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.connection-limits.node.ts:125:25)\n at async TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:20)\n at async TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:179:13)\n at async Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:532:9)" + } + } + Error details: + Error: Expected string to include "ECONNRESET" + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at StringMatchers.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/string.ts:25:27) + at Proxy.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:355:60) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.connection-limits.node.ts:125:25) + at async TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:20) + at async TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:179:13) + at async Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:532:9) + Error: Expected string to include "ECONNRESET" + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at StringMatchers.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/string.ts:25:27) + at Proxy.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:355:60) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.connection-limits.node.ts:125:25) + at async TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:20) + at async TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:179:13) + at async Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:532:9) + Test starting: Route-level connection limits +   info:  Connection established: ::ffff:127.0.0.1 -> localhost:5100 +   info:  Connection established: ::ffff:127.0.0.1 -> localhost:5100 + ❌ Route-level connection limits (0ms) + ⟦TSTEST:META:{"time":3,"retry":0,"error":{"message":"Expected string to include \"ECONNRESET\"","stack":"Error: Expected string to include \"ECONNRESET\"\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at StringMatchers.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/string.ts:25:27)\n at Proxy.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:355:60)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.connection-limits.node.ts:149:25)\n at async TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:20)\n at async TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:179:13)\n at async Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:532:9)"}}⟧ + ⟦TSTEST:ERROR⟧ + { + "testNumber": 3, + "error": { + "message": "Expected string to include \"ECONNRESET\"", + "stack": "Error: Expected string to include \"ECONNRESET\"\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at StringMatchers.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/string.ts:25:27)\n at Proxy.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:355:60)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.connection-limits.node.ts:149:25)\n at async TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:20)\n at async TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:179:13)\n at async Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:532:9)" + } + } + Error details: + Error: Expected string to include "ECONNRESET" + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at StringMatchers.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/string.ts:25:27) + at Proxy.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:355:60) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.connection-limits.node.ts:149:25) + at async TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:20) + at async TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:179:13) + at async Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:532:9) + Error: Expected string to include "ECONNRESET" + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at StringMatchers.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/string.ts:25:27) + at Proxy.toInclude (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:355:60) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.connection-limits.node.ts:149:25) + at async TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:20) + at async TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:179:13) + at async Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:532:9) + Test starting: Connection rate limiting + βœ… Connection rate limiting (160ms) + Test starting: HttpProxy per-IP validation + [INFO] Route manager configured with 0 routes across 0 ports  + [INFO] Updated RouteManager with 0 routes  + [WARN] CertificateManager is deprecated - use SmartCertManager instead  + [INFO] Loaded default certificates from filesystem (sync - deprecated)  + [INFO] WebSocket handler initialized  + [INFO] HttpProxy started on port 5102  +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 5101 reference count decreased to 0 +   WARN ->  [SUMMARY] Rejected 17 connections from 1 IPs in 5s (Maximum connections per IP (3) exceeded: 17) +Running tree kill with SIGTERM on process 833307 + ❌ Test file timeout (60000ms) + Error: Test file exceeded timeout of 60 seconds + Error details: + Test execution was terminated after 60 seconds +Running tree kill with SIGKILL on process 833307 + +⚠️ Error + Only 5 out of 8 completed! + +⚠️ Error + The amount of received tests and expectedTests is unequal! Therefore the testfile failed + Summary: 2 passed, 3 failed of 5 tests in 60.1s + +⚠️ Error + Only 5 out of 8 completed! + +⚠️ Error + The amount of received tests and expectedTests is unequal! Therefore the testfile failed + Summary: 2 passed, 3 failed of 5 tests in 60.1s + +▢️ test/test.fix-verification.ts (27/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: should verify certificate manager callback is preserved on updateRoutes +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +   WARN ->  1 configuration warnings found +   WARN ->  Port 18080 is not configured for any routes but is needed for ACME challenges. Add a route listening on port 18080 or ensure it's accessible for HTTP-01 challenges. +  debug  Port 18443 is used by 1 routes: cert-route +   info:  SmartProxy starting with 1 ports: 18443 +   info:  SmartProxy -> OK: Now listening on port 18443 +   info:  Using top-level ACME configuration with email: test@local.test +   info:  Starting certificate provisioning now that ports are ready +  debug  MetricsCollector started +   info:  Updating routes (1 routes) +  debug  Port 18443 is used by 1 routes: cert-route +  debug  Port 18444 is used by 1 routes: updated-route +  debug  Current listening ports: 18443 +  debug  Ports needed for new routes: 18444 +   info:  Port 18443 no longer has any associated routes, will be released +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +   info:  Releasing 1 orphaned ports: 18443 +  debug  Port 18443 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 18443 +   info:  Binding to 1 new ports: 18444 +   info:  SmartProxy -> OK: Now listening on port 18444 +  debug  ACME port 80 is not already in use by other routes +   info:  Challenge route successfully removed from routes +   info:  SmartProxy shutting down... +   info:  Certificate manager stopped +   info:  NFTablesManager stopped +  debug  Port 18444 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 18444 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + Fix verified: Certificate manager callback is preserved on updateRoutes + βœ… should verify certificate manager callback is preserved on updateRoutes (6ms) + Summary: 1/1 PASSED in 2.3s + +▢️ test/test.forwarding-fix-verification.ts (28/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: setup test server + Test server listening on port 6789 + βœ… setup test server (2ms) + Test starting: regular forward route should work correctly +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 7890 is used by 1 routes: Test Forward Route +   info:  SmartProxy starting with 1 ports: 7890 +   info:  SmartProxy -> OK: Now listening on port 7890 +   info:  No routes require certificate management +  debug  MetricsCollector started +   info:  New connection from ::ffff:127.0.0.1 on port 7890. Active connections: 1 + Client connected to proxy + Test server: Client connected +   info:  Connection established: ::ffff:127.0.0.1 -> localhost:6789 + Test server received: Test message +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 7890 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 7890 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… regular forward route should work correctly (16ms) + βœ… NFTables forward route should not terminate connections (requires root) (0ms) + Test skipped: Marked as skip + Test starting: cleanup +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… cleanup (0ms) +  debug  Connection n30849wpdo3seqc75cfma closed during immediate routing: immediate-route-client_closed + Test server: Client disconnected +   info:  [SUMMARY] 1 HttpProxy connections terminated in 0s + Summary: 4/4 PASSED in 2.4s + +▢️ test/test.forwarding-regression.ts (29/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: forward connections should not be immediately closed + Test server listening on port 9090 +   info:  Route manager configured with 1 routes across 1 ports +   info:  Port 8080: 1 routes (Forward Test Route) +   info:  Updated RouteManager with 1 routes +  debug  Port 8080 is used by 1 routes: Forward Test Route +   info:  SmartProxy starting with 1 ports: 8080 +   info:  SmartProxy -> OK: Now listening on port 8080 +   info:  No routes require certificate management +  debug  MetricsCollector started +  debug  MetricsCollector: New connection recorded +   info:  New connection from ::ffff:127.0.0.1 on port 8080. Keep-Alive: Enabled. Active connections: 1 +   info:  Route matched +  debug  Checking HttpProxy forwarding: port=8080, useHttpProxy=undefined, isHttpProxyPort=undefined, hasHttpProxy=false +   info:  Using basic forwarding to 127.0.0.1:9090 for connection zm56pjb04saqdwnsasl3i +   info:  Setting up direct connection zm56pjb04saqdwnsasl3i to 127.0.0.1:9090 + Client connected to proxy + Client connected to test server +   info:  Connection zm56pjb04saqdwnsasl3i established to target 127.0.0.1:9090 +   info:  Connection established: ::ffff:127.0.0.1 -> 127.0.0.1:9090 + Client received: Welcome from test server +  + Test server received: Hello from client + Client received: Echo: Hello from client +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8080 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8080 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… forward connections should not be immediately closed (211ms) +  debug  Connection zm56pjb04saqdwnsasl3i closed during immediate routing: immediate-route-client_closed + Client connection closed +   info:  [SUMMARY] 1 HttpProxy connections terminated in 0s + Summary: 1/1 PASSED in 2.5s + +▢️ test/test.forwarding.examples.ts (30/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: Route-based configuration examples + HTTP-only route created successfully: Basic HTTP Route + ❌ Route-based configuration examples (0ms) + ⟦TSTEST:META:{"time":1,"retry":0,"error":{"message":"Expected value to be true","stack":"Error: Expected value to be true\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at BooleanMatchers.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/boolean.ts:11:27)\n at Proxy.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:337:43)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.forwarding.examples.ts:49:68)\n at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26)\n at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34)\n at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39)"}}⟧ + ⟦TSTEST:ERROR⟧ + { + "testNumber": 1, + "error": { + "message": "Expected value to be true", + "stack": "Error: Expected value to be true\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at BooleanMatchers.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/boolean.ts:11:27)\n at Proxy.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:337:43)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.forwarding.examples.ts:49:68)\n at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26)\n at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34)\n at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39)" + } + } + Error details: + Error: Expected value to be true + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at BooleanMatchers.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/boolean.ts:11:27) + at Proxy.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:337:43) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.forwarding.examples.ts:49:68) + at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26) + at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34) + at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39) + Error: Expected value to be true + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at BooleanMatchers.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/boolean.ts:11:27) + at Proxy.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:337:43) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.forwarding.examples.ts:49:68) + at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26) + at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34) + at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39) + Test 1 failed with status error: + || Route-based configuration examples + || for more information please take a look the logs above + Summary: 0 passed, 1 failed of 1 tests in 2.3s + +▢️ test/test.forwarding.ts (31/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< + Test starting: Route Helpers - Create HTTP routes + βœ… Route Helpers - Create HTTP routes (1ms) + Test starting: Route Helpers - Create HTTPS terminate to HTTP routes + βœ… Route Helpers - Create HTTPS terminate to HTTP routes (0ms) + Test starting: Route Helpers - Create HTTPS passthrough routes + βœ… Route Helpers - Create HTTPS passthrough routes (1ms) + Test starting: Route Helpers - Create HTTPS to HTTPS routes + βœ… Route Helpers - Create HTTPS to HTTPS routes (0ms) + Test starting: Route Helpers - Create complete HTTPS server with redirect + βœ… Route Helpers - Create complete HTTPS server with redirect (0ms) + Summary: 5/5 PASSED in 2.3s + +▢️ test/test.forwarding.unit.ts (32/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< + Test starting: ForwardingHandlerFactory - apply defaults based on type + βœ… ForwardingHandlerFactory - apply defaults based on type (1ms) + Test starting: ForwardingHandlerFactory - factory function for handlers + βœ… ForwardingHandlerFactory - factory function for handlers (0ms) + Summary: 2/2 PASSED in 2.3s + +▢️ test/test.http-fix-unit.ts (33/78) + Runtime: node.js + Test starting: should forward non-TLS connections on HttpProxy ports + Using HttpProxy for non-TLS connection on port 8080 + Test passed: Non-TLS connections on HttpProxy ports are forwarded correctly + βœ… should forward non-TLS connections on HttpProxy ports (1ms) + Test starting: should use direct connection for non-HttpProxy ports + Using basic forwarding for port 8080 + Test passed: Non-HttpProxy ports use direct connection + βœ… should use direct connection for non-HttpProxy ports (0ms) + Test starting: should handle ACME HTTP-01 challenges on port 80 with HttpProxy + Using HttpProxy for ACME challenge on port 80 + Test passed: ACME HTTP-01 challenges on port 80 use HttpProxy + βœ… should handle ACME HTTP-01 challenges on port 80 with HttpProxy (0ms) + Summary: 3/3 PASSED in 1.2s + +▢️ test/test.http-fix-verification.ts (34/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: should detect and forward non-TLS connections on useHttpProxy ports +   info:  New connection from 127.0.0.1 on port 8080. Active connections: 1 + ❌ should detect and forward non-TLS connections on useHttpProxy ports (0ms) + ⟦TSTEST:META:{"time":2,"retry":0,"error":{"message":"this.smartProxy.connectionManager.trackConnectionByRoute is not a function","stack":"TypeError: this.smartProxy.connectionManager.trackConnectionByRoute is not a function\n at RouteConnectionHandler.handleForwardAction (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:751:39)\n at RouteConnectionHandler.routeConnection (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:638:21)\n at RouteConnectionHandler.handleInitialData (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:231:12)\n at RouteConnectionHandler.handleConnection (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:170:10)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-fix-verification.ts:118:11)\n at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26)\n at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34)\n at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-fix-verification.ts:252:20)"}}⟧ + ⟦TSTEST:ERROR⟧ + { + "testNumber": 1, + "error": { + "message": "this.smartProxy.connectionManager.trackConnectionByRoute is not a function", + "stack": "TypeError: this.smartProxy.connectionManager.trackConnectionByRoute is not a function\n at RouteConnectionHandler.handleForwardAction (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:751:39)\n at RouteConnectionHandler.routeConnection (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:638:21)\n at RouteConnectionHandler.handleInitialData (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:231:12)\n at RouteConnectionHandler.handleConnection (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:170:10)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-fix-verification.ts:118:11)\n at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26)\n at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34)\n at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-fix-verification.ts:252:20)" + } + } + Error details: + TypeError: this.smartProxy.connectionManager.trackConnectionByRoute is not a function + at RouteConnectionHandler.handleForwardAction (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:751:39) + at RouteConnectionHandler.routeConnection (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:638:21) + at RouteConnectionHandler.handleInitialData (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:231:12) + at RouteConnectionHandler.handleConnection (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:170:10) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-fix-verification.ts:118:11) + at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26) + at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34) + at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-fix-verification.ts:252:20) + TypeError: this.smartProxy.connectionManager.trackConnectionByRoute is not a function + at RouteConnectionHandler.handleForwardAction (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:751:39) + at RouteConnectionHandler.routeConnection (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:638:21) + at RouteConnectionHandler.handleInitialData (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:231:12) + at RouteConnectionHandler.handleConnection (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:170:10) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-fix-verification.ts:118:11) + at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26) + at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34) + at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-fix-verification.ts:252:20) + Test starting: should handle TLS connections normally +   info:  New connection from 127.0.0.1 on port 443. Active connections: 1 + /mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:751 + this.smartProxy.connectionManager.trackConnectionByRoute(record.routeId, record.id); + ^ +  +  + TypeError: this.smartProxy.connectionManager.trackConnectionByRoute is not a function + at RouteConnectionHandler.handleForwardAction (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:751:39) + at RouteConnectionHandler.routeConnection (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:638:21) + at processInitialData (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:385:12) + at Object._dataHandler (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/smart-proxy/route-connection-handler.ts:446:7) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-fix-verification.ts:243:16) + at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26) + at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34) + at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39) +  + Node.js v23.8.0 + +⚠️ Error + Only 1 out of 2 completed! + +⚠️ Error + The amount of received tests and expectedTests is unequal! Therefore the testfile failed + Summary: 0 passed, 1 failed of 1 tests in 2.2s + +▢️ test/test.http-forwarding-fix.ts (35/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: should detect and forward non-TLS connections on HttpProxy ports +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 8081 is used by 1 routes: test-http-forward +   info:  SmartProxy starting with 1 ports: 8081 + Mock: HttpProxyBridge initialized + Mock: HttpProxyBridge started +   info:  SmartProxy -> OK: Now listening on port 8081 (HttpProxy forwarding enabled) +   info:  No routes require certificate management +  debug  MetricsCollector started +  debug  MetricsCollector: New connection recorded +   info:  New connection from ::ffff:127.0.0.1 on port 8081. Keep-Alive: Enabled. Active connections: 1 +   info:  Route matched +  debug  Checking HttpProxy forwarding: port=8081, useHttpProxy=[8081], isHttpProxyPort=true, hasHttpProxy=true +   info:  Using HttpProxy for non-TLS connection jre2vz42dd8fwv54ytr2vu on port 8081 + Mock: Connection forwarded to HttpProxy with args: jre2vz42dd8fwv54ytr2vu on port: 8081 + Client connected to proxy on port 8081 +  debug  Connection jre2vz42dd8fwv54ytr2vu closed during immediate routing: immediate-route-client_closed + About to stop proxy... +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8081 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8081 +   info:  All servers closed. Cleaning up active connections... + Mock: HttpProxyBridge stopped +  debug  MetricsCollector stopped +   info:  [SUMMARY] 1 HttpProxy connections terminated in 0s +   info:  SmartProxy shutdown complete. + Proxy stopped + βœ… should detect and forward non-TLS connections on HttpProxy ports (267ms) + Test starting: should properly detect non-TLS connections on HttpProxy ports + Target server listening on port 8182 +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 8082 is used by 1 routes: test-route +   info:  SmartProxy starting with 1 ports: 8082 + Mock: HttpProxyBridge initialized + Mock: HttpProxyBridge started +   info:  SmartProxy -> OK: Now listening on port 8082 (HttpProxy forwarding enabled) +   info:  No routes require certificate management +  debug  MetricsCollector started +   info:  New connection from ::ffff:127.0.0.1 on port 8082. Active connections: 1 + HttpProxy forward called with connectionId: 95zydwak23lsk0y0ozjkza + Connected to proxy +  debug  Connection 95zydwak23lsk0y0ozjkza closed during immediate routing: immediate-route-client_closed +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8082 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8082 +   info:  All servers closed. Cleaning up active connections... + Mock: HttpProxyBridge stopped +  debug  MetricsCollector stopped +   info:  [SUMMARY] 1 HttpProxy connections terminated in 0s +   info:  SmartProxy shutdown complete. + βœ… should properly detect non-TLS connections on HttpProxy ports (254ms) + Summary: 2/2 PASSED in 2.8s + +▢️ test/test.http-port8080-forwarding.ts (36/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: should forward HTTP connections on port 8080 + Target server listening on port 8181 +   info:  Route manager configured with 1 routes across 1 ports +   info:  Port 8080: 1 routes (test-route) +   info:  Updated RouteManager with 1 routes +  debug  Port 8080 is used by 1 routes: test-route +   info:  SmartProxy starting with 1 ports: 8080 +   info:  SmartProxy -> OK: Now listening on port 8080 +   info:  No routes require certificate management +  debug  MetricsCollector started + Making HTTP request to proxy... +  debug  MetricsCollector: New connection recorded +   info:  New connection from ::ffff:127.0.0.1 on port 8080. Keep-Alive: Enabled. Active connections: 1 +   info:  Route matched +  debug  Checking HttpProxy forwarding: port=8080, useHttpProxy=undefined, isHttpProxyPort=undefined, hasHttpProxy=false +   info:  Using basic forwarding to localhost:8181 for connection y05lajr7vqjonay9ddvjr +   info:  Setting up direct connection y05lajr7vqjonay9ddvjr to localhost:8181 +   info:  Connection y05lajr7vqjonay9ddvjr established to target localhost:8181 +   info:  Connection established: ::ffff:127.0.0.1 -> localhost:8181 + Target server received: GET /.well-known/acme-challenge/test-token + Got response from proxy: 200 +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8080 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8080 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. +  debug  Connection y05lajr7vqjonay9ddvjr closed during immediate routing: immediate-route-client_closed + βœ… should forward HTTP connections on port 8080 (5023ms) + Test starting: should handle basic HTTP request forwarding + Target server listening on port 8182 +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 8081 is used by 1 routes: simple-forward +   info:  SmartProxy starting with 1 ports: 8081 +   info:  SmartProxy -> OK: Now listening on port 8081 +   info:  No routes require certificate management +  debug  MetricsCollector started + Making HTTP request to proxy... +   info:  New connection from ::ffff:127.0.0.1 on port 8081. Active connections: 1 +   info:  Connection established: ::ffff:127.0.0.1 -> localhost:8182 + Target received: GET /test from test.local + Got response from proxy: 200 + Received data chunk: Hello from target +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8081 reference count decreased to 0 +   info:  [SUMMARY] 1 HttpProxy connections terminated in 5s +   info:  SmartProxy -> Stopped listening on port 8081 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. +  debug  Connection 7ao4scehajgaukg2zsboo closed during immediate routing: immediate-route-client_closed +   info:  [SUMMARY] 1 HttpProxy connections terminated in 0s + βœ… should handle basic HTTP request forwarding (5003ms) + Summary: 2/2 PASSED in 12.4s + +▢️ test/test.http-port8080-simple.ts (37/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: should handle ACME challenges on port 8080 with improved port binding intelligence + Target server listening on port 9001 + Creating SmartProxy with ACME port 8080... +   info:  Route manager configured with 2 routes across 2 ports +   info:  Port 9003: 1 routes (test-route) +   info:  Port 9009: 1 routes (http-route) +   info:  Updated RouteManager with 2 routes + Mocking certificate manager... + Starting SmartProxy... +  debug  Port 9003 is used by 1 routes: test-route +  debug  Port 9009 is used by 1 routes: http-route +   info:  SmartProxy starting with 2 ports: 9003, 9009 +   info:  SmartProxy -> OK: Now listening on port 9003 +   info:  SmartProxy -> OK: Now listening on port 9009 +   info:  Using top-level ACME configuration with email: test@example.com +   info:  Starting certificate provisioning now that ports are ready + Mock: Provisioning certificates +  debug  MetricsCollector started + Port binding attempts: [ 9003, 9009 ] + Actually bound ports: [ 9003, 9009 ] + Testing route update with port reuse... +   info:  Updating routes (3 routes) +  debug  Port 9003 is used by 1 routes: test-route +  debug  Port 9009 is used by 1 routes: http-route +  debug  Port 9003 is used by 1 routes: test-route +  debug  Port 9009 is used by 2 routes: http-route, additional-route +  debug  Current listening ports: 9003, 9009 +  debug  Ports needed for new routes: 9003, 9009 +   info:  Route manager configured with 3 routes across 2 ports +   info:  Port 9003: 1 routes (test-route) +   info:  Port 9009: 2 routes (http-route, additional-route) +   info:  Updated RouteManager with 3 routes +  debug  ACME port 9009 is already in use by other routes +   info:  Challenge route successfully removed from routes + Port binding attempts after update: [] + Bound ports after update: [ 9003, 9009 ] + Port binding intelligence verified successfully! + Cleaning up... +   info:  SmartProxy shutting down... +   info:  Certificate manager stopped +   info:  NFTablesManager stopped +  debug  Port 9003 reference count decreased to 0 +  debug  Port 9009 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 9003 +   info:  SmartProxy -> Stopped listening on port 9009 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. + βœ… should handle ACME challenges on port 8080 with improved port binding intelligence (8ms) + Summary: 1/1 PASSED in 2.3s + +▢️ test/test.http-proxy-security-limits.node.ts (38/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< + Test starting: Setup HttpProxy SecurityManager + βœ… Setup HttpProxy SecurityManager (0ms) + Test starting: HttpProxy IP connection tracking + βœ… HttpProxy IP connection tracking (1ms) + Test starting: HttpProxy connection rate limiting + ❌ HttpProxy connection rate limiting (0ms) + ⟦TSTEST:META:{"time":0,"retry":0,"error":{"message":"Expected value to be true","stack":"Error: Expected value to be true\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at BooleanMatchers.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/boolean.ts:11:27)\n at Proxy.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:337:43)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-proxy-security-limits.node.ts:51:28)\n at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26)\n at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34)\n at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39)"}}⟧ + ⟦TSTEST:ERROR⟧ + { + "testNumber": 3, + "error": { + "message": "Expected value to be true", + "stack": "Error: Expected value to be true\n at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15)\n at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16)\n at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5)\n at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17)\n at BooleanMatchers.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/boolean.ts:11:27)\n at Proxy.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:337:43)\n at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-proxy-security-limits.node.ts:51:28)\n at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26)\n at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34)\n at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39)" + } + } + Error details: + Error: Expected value to be true + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at BooleanMatchers.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/boolean.ts:11:27) + at Proxy.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:337:43) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-proxy-security-limits.node.ts:51:28) + at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26) + at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34) + at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39) + Error: Expected value to be true + at (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:299:15) + at runDirectOrNegated (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:214:16) + at Proxy.runCheck (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:279:5) + at Proxy.customAssertion (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:294:17) + at BooleanMatchers.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/namespaces/boolean.ts:11:27) + at Proxy.toBeTrue (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@push.rocks+smartexpect@2.5.0/node_modules/@push.rocks/smartexpect/ts/smartexpect.classes.assertion.ts:337:43) + at (/mnt/data/lossless/push.rocks/smartproxy/test/test.http-proxy-security-limits.node.ts:51:28) + at TapTest.currentTest.testFunction (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:514:26) + at TapTest.run (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.taptest.ts:176:34) + at Tap.start (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/@git.zone+tstest@2.3.1_@aws-sdk+credential-providers@3.798.0_socks@2.8.4_typescript@5.8.3/node_modules/@git.zone/tstest/ts_tapbundle/tapbundle.classes.tap.ts:528:39) + Test starting: HttpProxy CLIENT_IP header handling + βœ… HttpProxy CLIENT_IP header handling (0ms) + Test starting: HttpProxy automatic cleanup + βœ… HttpProxy automatic cleanup (102ms) + Test starting: Cleanup HttpProxy SecurityManager + βœ… Cleanup HttpProxy SecurityManager (0ms) + Test 3 failed with status error: + || HttpProxy connection rate limiting + || for more information please take a look the logs above + Summary: 5 passed, 1 failed of 6 tests in 2.3s + +▢️ test/test.httpproxy.function-targets.ts (39/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: setup HttpProxy function-based targets test environment + [INFO] Route manager configured with 0 routes across 0 ports  + [INFO] Updated RouteManager with 0 routes  + [WARN] CertificateManager is deprecated - use SmartCertManager instead  + [INFO] Loaded default certificates from filesystem (sync - deprecated)  + [INFO] WebSocket handler initialized  + [INFO] HttpProxy started on port 0  + HttpProxy actual listening port: 44271 + βœ… setup HttpProxy function-based targets test environment (5ms) + Test starting: should support static host/port routes + [INFO] Updating route configurations (1 routes)  + [INFO] Route manager configured with 1 routes across 1 ports  + [INFO] Updated RouteManager with 1 routes  + HttpRouter initialized with 1 routes (1 unique hosts) + [INFO] HttpRouter initialized with 1 routes (1 unique hosts)  + HttpRouter initialized with 1 routes (1 unique hosts) + [WARN] updateRoutes is deprecated - use SmartCertManager instead  + [INFO] HttpRouter initialized with 1 routes (1 unique hosts)  + [INFO] Route configuration updated with 1 routes  + βœ… should support static host/port routes (56ms) + Test starting: should support function-based host + [INFO] Updating route configurations (1 routes)  + [INFO] Route manager configured with 1 routes across 1 ports  + [INFO] Updated RouteManager with 1 routes  + HttpRouter initialized with 1 routes (1 unique hosts) + [INFO] HttpRouter initialized with 1 routes (1 unique hosts)  + HttpRouter initialized with 1 routes (1 unique hosts) + [INFO] HttpRouter initialized with 1 routes (1 unique hosts)  + [WARN] updateRoutes is deprecated - use SmartCertManager instead  + [INFO] Route configuration updated with 1 routes  + βœ… should support function-based host (45ms) + Test starting: should support function-based port + [INFO] Updating route configurations (1 routes)  + [INFO] Route manager configured with 1 routes across 1 ports  + [INFO] Updated RouteManager with 1 routes  + HttpRouter initialized with 1 routes (1 unique hosts) + [INFO] HttpRouter initialized with 1 routes (1 unique hosts)  + HttpRouter initialized with 1 routes (1 unique hosts) + [INFO] HttpRouter initialized with 1 routes (1 unique hosts)  + [INFO] Route configuration updated with 1 routes  + [WARN] updateRoutes is deprecated - use SmartCertManager instead  + βœ… should support function-based port (44ms) + Test starting: should support function-based host AND port + [INFO] Updating route configurations (1 routes)  + [INFO] Route manager configured with 1 routes across 1 ports  + [INFO] Updated RouteManager with 1 routes  + HttpRouter initialized with 1 routes (1 unique hosts) + [INFO] HttpRouter initialized with 1 routes (1 unique hosts)  + HttpRouter initialized with 1 routes (1 unique hosts) + [INFO] HttpRouter initialized with 1 routes (1 unique hosts)  + [INFO] Route configuration updated with 1 routes  + [WARN] updateRoutes is deprecated - use SmartCertManager instead  + βœ… should support function-based host AND port (44ms) + Test starting: should support context-based routing with path + [INFO] Updating route configurations (1 routes)  + [INFO] Route manager configured with 1 routes across 1 ports  + [INFO] Updated RouteManager with 1 routes  + HttpRouter initialized with 1 routes (1 unique hosts) + [INFO] HttpRouter initialized with 1 routes (1 unique hosts)  + HttpRouter initialized with 1 routes (1 unique hosts) + [INFO] HttpRouter initialized with 1 routes (1 unique hosts)  + [INFO] Route configuration updated with 1 routes  + [WARN] updateRoutes is deprecated - use SmartCertManager instead  + βœ… should support context-based routing with path (46ms) + Test starting: cleanup HttpProxy function-based targets test environment + Test server closed successfully + HTTP/2 test server closed successfully + Stopping HttpProxy... + [INFO] Stopping HttpProxy server  + [INFO] Closing 0 WebSocket connections  + [INFO] Function cache cleared  + [INFO] HttpProxy server stopped successfully  + HttpProxy stopped successfully + βœ… cleanup HttpProxy function-based targets test environment (2ms) + Summary: 7/7 PASSED in 2.5s + +▢️ test/test.httpproxy.ts (40/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: setup test environment + [TEST] Loading and validating certificates + [TEST] Certificates loaded and validated + [TEST SERVER] Creating WebSocket server + Test server listening on port 3100 + βœ… setup test environment (3ms) + Test starting: should create proxy instance + [INFO] Route manager configured with 0 routes across 0 ports  + [INFO] Updated RouteManager with 0 routes  + [WARN] CertificateManager is deprecated - use SmartCertManager instead  + [INFO] Loaded default certificates from filesystem (sync - deprecated)  + βœ… should create proxy instance (2ms) + Test starting: should create proxy instance with extended options + [INFO] Route manager configured with 0 routes across 0 ports  + [INFO] Updated RouteManager with 0 routes  + [WARN] CertificateManager is deprecated - use SmartCertManager instead  + [INFO] Loaded default certificates from filesystem (sync - deprecated)  + βœ… should create proxy instance with extended options (0ms) + Test starting: should start the proxy server + [INFO] Route manager configured with 0 routes across 0 ports  + [INFO] Updated RouteManager with 0 routes  + [INFO] Loaded default certificates from filesystem (sync - deprecated)  + [WARN] CertificateManager is deprecated - use SmartCertManager instead  + [INFO] Updating route configurations (1 routes)  + [INFO] Route manager configured with 1 routes across 1 ports  + [INFO] Updated RouteManager with 1 routes  + HttpRouter initialized with 1 routes (2 unique hosts) + [INFO] HttpRouter initialized with 1 routes (2 unique hosts)  + HttpRouter initialized with 1 routes (2 unique hosts) + [WARN] updateRoutes is deprecated - use SmartCertManager instead  + [INFO] HttpRouter initialized with 1 routes (2 unique hosts)  + [INFO] Route configuration updated with 1 routes  + [INFO] WebSocket handler initialized  + [INFO] HttpProxy started on port 3001  + βœ… should start the proxy server (4ms) + Test starting: should route HTTPS requests based on host header + [TEST] Making HTTPS request: { + hostname: 'localhost', + port: 3001, + path: '/', + method: 'GET', + headers: { host: 'push.rocks' } + } + [TEST SERVER] Received HTTP request: { + url: '/', + method: 'GET', + headers: { host: 'localhost:3100', connection: 'keep-alive' } + } + [TEST] Received HTTPS response: { + statusCode: 200, + headers: { + 'access-control-allow-origin': '*', + 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'access-control-allow-headers': 'Content-Type, Authorization', + 'access-control-max-age': '86400', + server: 'NetworkProxy', + 'content-type': 'text/plain', + date: 'Sun, 20 Jul 2025 13:18:47 GMT', + connection: 'keep-alive', + 'keep-alive': 'timeout=5', + 'transfer-encoding': 'chunked' + } + } + [TEST] Response completed: { data: 'Hello from test server!' } + βœ… should route HTTPS requests based on host header (56ms) + Test starting: should handle unknown host headers + [TEST] Making HTTPS request: { + hostname: 'localhost', + port: 3001, + path: '/', + method: 'GET', + headers: { host: 'unknown.host' } + } + [WARN] No route configuration for host: unknown.host  + [TEST] Received HTTPS response: { + statusCode: 404, + headers: { + 'access-control-allow-origin': '*', + 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'access-control-allow-headers': 'Content-Type, Authorization', + 'access-control-max-age': '86400', + server: 'NetworkProxy', + date: 'Sun, 20 Jul 2025 13:18:47 GMT', + connection: 'keep-alive', + 'content-length': '47' + } + } + [TEST] Response completed: { data: 'Not Found: No route configuration for this host' } + βœ… should handle unknown host headers (5ms) + Test starting: should support WebSocket connections + [TEST] Testing WebSocket connection + [TEST] Creating WebSocket to wss://localhost:3001/ with host header: push.rocks + [TEST] WebSocket connected + [TEST] Sending WebSocket message: Hello WebSocket! + [TEST SERVER] Received WebSocket upgrade request: { + url: '/', + method: 'GET', + headers: { + host: 'localhost:3100', + upgrade: 'websocket', + connection: 'Upgrade', + 'sec-websocket-key': 'ON2Sz/WSh791AGV0Ntb4Yw==', + 'sec-websocket-version': '13', + 'sec-websocket-protocol': undefined + } + } + [TEST SERVER] Handling WebSocket upgrade + Test server: WebSocket headers: [ + 'HTTP/1.1 101 Switching Protocols', + 'Upgrade: websocket', + 'Connection: Upgrade', + 'Sec-WebSocket-Accept: Mu1VkcnDG6ULmepX5/X6Uzq29XM=' + ] + [TEST SERVER] WebSocket connection upgraded + [TEST SERVER] WebSocket connection established: { + url: '/', + headers: { + host: 'localhost:3100', + upgrade: 'websocket', + connection: 'Upgrade', + 'sec-websocket-key': 'ON2Sz/WSh791AGV0Ntb4Yw==', + 'sec-websocket-version': '13', + 'sec-websocket-protocol': undefined + } + } + [TEST] No message received after 2 seconds + [TEST] WebSocket test error: Error: Message timeout + at Timeout._onTimeout (/mnt/data/lossless/push.rocks/smartproxy/test/test.httpproxy.ts:363:49) + at listOnTimeout (node:internal/timers:614:17) + at process.processTimers (node:internal/timers:549:7) + [TEST] WebSocket test failed, continuing with other tests + βœ… should support WebSocket connections (3010ms) + Test starting: should handle custom headers + [INFO] Adding default headers { 'X-Proxy-Header': 'test-value' } + [INFO] Updated default response headers  + [TEST] Making HTTPS request: { + hostname: 'localhost', + port: 3001, + path: '/', + method: 'GET', + headers: { host: 'push.rocks' } + } + [ERROR] Error closing wsOutgoing: TypeError: First argument must be a valid error code number + at Sender.close (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/ws@8.18.2/node_modules/ws/lib/sender.js:187:13) + at WebSocket.close (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/ws@8.18.2/node_modules/ws/lib/websocket.js:315:18) + at WebSocket. (/mnt/data/lossless/push.rocks/smartproxy/ts/proxies/http-proxy/websocket-handler.ts:503:26) + at WebSocket.emit (node:events:519:35) + at WebSocket.emitClose (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/ws@8.18.2/node_modules/ws/lib/websocket.js:272:10) + at TLSSocket.socketOnClose (/mnt/data/lossless/push.rocks/smartproxy/node_modules/.pnpm/ws@8.18.2/node_modules/ws/lib/websocket.js:1341:15) + at TLSSocket.emit (node:events:519:35) + at node:net:351:12 + at Socket.done (node:_tls_wrap:650:7) + at Object.onceWrapper (node:events:622:26) + [TEST SERVER] Received HTTP request: { + url: '/', + method: 'GET', + headers: { host: 'localhost:3100', connection: 'keep-alive' } + } + [TEST] Received HTTPS response: { + statusCode: 200, + headers: { + 'access-control-allow-origin': '*', + 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'access-control-allow-headers': 'Content-Type, Authorization', + 'access-control-max-age': '86400', + 'x-proxy-header': 'test-value', + server: 'NetworkProxy', + 'content-type': 'text/plain', + date: 'Sun, 20 Jul 2025 13:18:50 GMT', + connection: 'keep-alive', + 'keep-alive': 'timeout=5', + 'transfer-encoding': 'chunked' + } + } + [TEST] Response completed: { data: 'Hello from test server!' } + βœ… should handle custom headers (5ms) + Test starting: should handle CORS preflight requests + [TEST] Making HTTPS request: { + hostname: 'localhost', + port: 3001, + path: '/', + method: 'OPTIONS', + headers: { + host: 'push.rocks', + origin: 'https://example.com', + 'access-control-request-method': 'POST', + 'access-control-request-headers': 'content-type' + } + } + [TEST] Received HTTPS response: { + statusCode: 204, + headers: { + 'access-control-allow-origin': '*', + 'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS', + 'access-control-allow-headers': 'Content-Type, Authorization', + 'access-control-max-age': '86400', + date: 'Sun, 20 Jul 2025 13:18:50 GMT', + connection: 'keep-alive' + } + } + [TEST] Response completed: { data: '' } + βœ… should handle CORS preflight requests (1ms) + Test starting: should track connections and metrics + βœ… should track connections and metrics (1ms) + Test starting: should update capacity settings + [INFO] Updated max connections to 2000  + [INFO] Updated keep-alive timeout to 60000ms  + [INFO] Updated connection pool size to 25  + βœ… should update capacity settings (0ms) + Test starting: should handle certificate requests + βœ… should handle certificate requests (0ms) + Test starting: should update certificates directly + [WARN] requestCertificate is deprecated - use SmartCertManager instead  + [INFO] Updating certificate for test.example.com  + [INFO] Certificate updated for test.example.com  + βœ… should update certificates directly (0ms) + Test starting: cleanup + [TEST] Starting cleanup + [TEST] Terminating 1 WebSocket clients + [TEST] Closing WebSocket server + [TEST SERVER] WebSocket connection closed: { code: 1006, reason: '', wasClean: false } + Test server: WebSocket server closed + [TEST] WebSocket server closed + [TEST] Closing test server + [TEST] Test server closed + [TEST] Stopping proxy + [INFO] Stopping HttpProxy server  + [INFO] Closing 0 WebSocket connections  + [INFO] Function cache cleared  + [INFO] HttpProxy server stopped successfully  + [TEST] Proxy stopped successfully + [TEST] Cleanup complete + βœ… cleanup (1ms) + [TEST] WebSocket server close timeout + [TEST] Test server close timeout + [TEST] Proxy stop timeout + Summary: 14/14 PASSED in 7.4s + +▢️ test/test.keepalive-support.node.ts (41/78) + Runtime: node.js + called svDb() on >SmartDataDbDoc._createdAt< + called svDb() on >SmartDataDbDoc._updatedAt< +   info:  Logger initialized + Test starting: keepalive support - verify keepalive connections are properly handled +  + === KeepAlive Support Test === + Purpose: Verify that keepalive connections are not prematurely cleaned up + βœ“ Echo backend started on port 9998 +  + --- Test 1: Standard KeepAlive Treatment --- +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 8590 is used by 1 routes: keepalive-route +   info:  SmartProxy starting with 1 ports: 8590 +   info:  SmartProxy -> OK: Now listening on port 8590 +   info:  No routes require certificate management +  debug  MetricsCollector started + βœ“ Proxy with standard keepalive started on port 8590 +   info:  New connection from ::ffff:127.0.0.1 on port 8590. Active connections: 1 + Client connected +   info:  Connection established: ::ffff:127.0.0.1 -> localhost:9998 + Received echo: Hello keepalive + KeepAlive connection 0gfejvdhf245g3t9m4232f: hasKeepAlive=true +   WARN ->  Timeout event on outgoing keep-alive connection 0gfejvdhf245g3t9m4232f from ::ffff:127.0.0.1 after 1h. Connection preserved. +   WARN ->  Timeout event on incoming keep-alive connection 0gfejvdhf245g3t9m4232f from ::ffff:127.0.0.1 after 1h. Connection preserved. + Socket timeout: server + Socket timeout: immediate-route-client + Socket timeout: client + Connections after 6s wait: 1 +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8590 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8590 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. +  debug  Connection 0gfejvdhf245g3t9m4232f closed during immediate routing: immediate-route-client_closed + Backend socket error (expected during cleanup): ECONNRESET +  + --- Test 2: Extended KeepAlive Treatment --- +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 8591 is used by 1 routes: keepalive-extended +   info:  SmartProxy starting with 1 ports: 8591 +   info:  SmartProxy -> OK: Now listening on port 8591 +   info:  No routes require certificate management +  debug  MetricsCollector started + βœ“ Proxy with extended keepalive started on port 8591 +   info:  New connection from ::ffff:127.0.0.1 on port 8591. Active connections: 1 + Client connected with extended timeout +   info:  Connection established: ::ffff:127.0.0.1 -> localhost:9998 + Extended connection assnnwem5hkzviq224859: hasKeepAlive=true, treatment=extended +   info:  [SUMMARY] 1 HttpProxy connections terminated in 4s + Connections after 3s (base timeout exceeded): 1 +   info:  SmartProxy shutting down... +   info:  NFTablesManager stopped +  debug  Port 8591 reference count decreased to 0 +   info:  SmartProxy -> Stopped listening on port 8591 +   info:  All servers closed. Cleaning up active connections... +  debug  MetricsCollector stopped +   info:  SmartProxy shutdown complete. +  debug  Connection assnnwem5hkzviq224859 closed during immediate routing: immediate-route-client_closed +  + --- Test 3: Immortal KeepAlive Treatment --- +   info:  Route manager configured with 1 routes across 1 ports +   info:  Updated RouteManager with 1 routes +  debug  Port 8592 is used by 1 routes: keepalive-immortal +   info:  SmartProxy starting with 1 ports: 8592 +   info:  SmartProxy -> OK: Now listening on port 8592 +   info:  No routes require certificate management +  debug  MetricsCollector started + βœ“ Proxy with immortal keepalive started on port 8592 +   info:  New connection from ::ffff:127.0.0.1 on port 8592. Active connections: 1 + Client connected with immortal treatment +   info:  Connection established: ::ffff:127.0.0.1 -> localhost:9998 diff --git a/test/core/routing/test.path-matcher.ts b/test/core/routing/test.path-matcher.ts index a1a9ad9..fa6f531 100644 --- a/test/core/routing/test.path-matcher.ts +++ b/test/core/routing/test.path-matcher.ts @@ -32,14 +32,14 @@ tap.test('PathMatcher - wildcard matching', async () => { const result = PathMatcher.match('/api/*', '/api/users/123/profile'); expect(result.matches).toEqual(true); expect(result.pathMatch).toEqual('/api'); // Normalized without trailing slash - expect(result.pathRemainder).toEqual('users/123/profile'); + expect(result.pathRemainder).toEqual('/users/123/profile'); }); tap.test('PathMatcher - mixed parameters and wildcards', async () => { const result = PathMatcher.match('/api/:version/*', '/api/v1/users/123'); expect(result.matches).toEqual(true); expect(result.params).toEqual({ version: 'v1' }); - expect(result.pathRemainder).toEqual('users/123'); + expect(result.pathRemainder).toEqual('/users/123'); }); tap.test('PathMatcher - trailing slash normalization', async () => { diff --git a/test/core/utils/test.shared-security-manager.ts b/test/core/utils/test.shared-security-manager.ts index 38cfdb9..0619810 100644 --- a/test/core/utils/test.shared-security-manager.ts +++ b/test/core/utils/test.shared-security-manager.ts @@ -58,7 +58,7 @@ tap.test('Shared Security Manager', async () => { }, action: { type: 'forward', - target: { host: 'target.com', port: 443 } + targets: [{ host: 'target.com', port: 443 }] }, security: { ipAllowList: ['10.0.0.*', '192.168.1.*'], @@ -113,7 +113,7 @@ tap.test('Shared Security Manager', async () => { }, action: { type: 'forward', - target: { host: 'target.com', port: 443 } + targets: [{ host: 'target.com', port: 443 }] }, security: { rateLimit: { diff --git a/test/test.acme-route-creation.ts b/test/test.acme-route-creation.ts index 2901d03..e4dabdc 100644 --- a/test/test.acme-route-creation.ts +++ b/test/test.acme-route-creation.ts @@ -59,7 +59,7 @@ tap.test('should create ACME challenge route', async (tools) => { }, action: { type: 'forward' as const, - target: { host: 'localhost', port: 8080 } + targets: [{ host: 'localhost', port: 8080 }] } }, challengeRoute diff --git a/test/test.acme-timing-simple.ts b/test/test.acme-timing-simple.ts index 91be3bb..58b8d81 100644 --- a/test/test.acme-timing-simple.ts +++ b/test/test.acme-timing-simple.ts @@ -18,7 +18,7 @@ tap.test('should defer certificate provisioning until ports are ready', async (t }, action: { type: 'forward', - target: { host: 'localhost', port: 8181 }, + targets: [{ host: 'localhost', port: 8181 }], tls: { mode: 'terminate', certificate: 'auto', diff --git a/test/test.acme-timing.ts b/test/test.acme-timing.ts index a594f4a..33677d7 100644 --- a/test/test.acme-timing.ts +++ b/test/test.acme-timing.ts @@ -30,7 +30,7 @@ tap.test('should defer certificate provisioning until after ports are listening' }, action: { type: 'forward', - target: { host: 'localhost', port: 8181 }, + targets: [{ host: 'localhost', port: 8181 }], tls: { mode: 'terminate', certificate: 'auto', @@ -126,7 +126,7 @@ tap.test('should have ACME challenge route ready before certificate provisioning }, action: { type: 'forward', - target: { host: 'localhost', port: 8181 }, + targets: [{ host: 'localhost', port: 8181 }], tls: { mode: 'terminate', certificate: 'auto' diff --git a/test/test.certificate-acme-update.ts b/test/test.certificate-acme-update.ts index 47955aa..29c9e42 100644 --- a/test/test.certificate-acme-update.ts +++ b/test/test.certificate-acme-update.ts @@ -16,10 +16,10 @@ tap.test('SmartCertManager should call getCertificateForDomain with wildcard opt }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 8080 - }, + }], tls: { mode: 'terminate', certificate: 'auto', diff --git a/test/test.certificate-provision.ts b/test/test.certificate-provision.ts index 74c46c3..8c67213 100644 --- a/test/test.certificate-provision.ts +++ b/test/test.certificate-provision.ts @@ -59,10 +59,10 @@ tap.test('SmartProxy should support custom certificate provision function', asyn }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 8080 - }, + }], tls: { mode: 'terminate', certificate: 'auto' @@ -109,10 +109,10 @@ tap.test('Custom certificate provision function should be called', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 8080 - }, + }], tls: { mode: 'terminate', certificate: 'auto' @@ -172,10 +172,10 @@ tap.test('Should fallback to ACME when custom provision fails', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 8080 - }, + }], tls: { mode: 'terminate', certificate: 'auto' @@ -231,10 +231,10 @@ tap.test('Should not fallback when certProvisionFallbackToAcme is false', async }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 8080 - }, + }], tls: { mode: 'terminate', certificate: 'auto' @@ -310,10 +310,10 @@ tap.test('Should return http01 for unknown domains', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 8080 - }, + }], tls: { mode: 'terminate', certificate: 'auto' diff --git a/test/test.certificate-provisioning.ts b/test/test.certificate-provisioning.ts index b27a959..852d9b0 100644 --- a/test/test.certificate-provisioning.ts +++ b/test/test.certificate-provisioning.ts @@ -7,7 +7,7 @@ const testProxy = new SmartProxy({ match: { ports: 9443, domains: 'test.local' }, action: { type: 'forward', - target: { host: 'localhost', port: 8080 }, + targets: [{ host: 'localhost', port: 8080 }], tls: { mode: 'terminate', certificate: 'auto', @@ -67,7 +67,7 @@ tap.test('should handle static certificates', async () => { match: { ports: 9444, domains: 'static.example.com' }, action: { type: 'forward', - target: { host: 'localhost', port: 8080 }, + targets: [{ host: 'localhost', port: 8080 }], tls: { mode: 'terminate', certificate: { @@ -96,7 +96,7 @@ tap.test('should handle ACME challenge routes', async () => { match: { ports: 9445, domains: 'acme.local' }, action: { type: 'forward', - target: { host: 'localhost', port: 8080 }, + targets: [{ host: 'localhost', port: 8080 }], tls: { mode: 'terminate', certificate: 'auto', @@ -112,7 +112,7 @@ tap.test('should handle ACME challenge routes', async () => { match: { ports: 9081, domains: 'acme.local' }, action: { type: 'forward', - target: { host: 'localhost', port: 8080 } + targets: [{ host: 'localhost', port: 8080 }] } }], acme: { @@ -167,7 +167,7 @@ tap.test('should renew certificates', async () => { match: { ports: 9446, domains: 'renew.local' }, action: { type: 'forward', - target: { host: 'localhost', port: 8080 }, + targets: [{ host: 'localhost', port: 8080 }], tls: { mode: 'terminate', certificate: 'auto', diff --git a/test/test.certificate-simple.ts b/test/test.certificate-simple.ts index e9d832e..85a21d7 100644 --- a/test/test.certificate-simple.ts +++ b/test/test.certificate-simple.ts @@ -8,7 +8,7 @@ tap.test('should create SmartProxy with certificate routes', async () => { match: { ports: 8443, domains: 'test.example.com' }, action: { type: 'forward', - target: { host: 'localhost', port: 8080 }, + targets: [{ host: 'localhost', port: 8080 }], tls: { mode: 'terminate', certificate: 'auto', diff --git a/test/test.cleanup-queue-bug.node.ts b/test/test.cleanup-queue-bug.node.ts index 7c47774..88e7134 100644 --- a/test/test.cleanup-queue-bug.node.ts +++ b/test/test.cleanup-queue-bug.node.ts @@ -13,7 +13,7 @@ tap.test('cleanup queue bug - verify queue processing handles more than batch si match: { ports: 8588 }, action: { type: 'forward', - target: { host: 'localhost', port: 9996 } + targets: [{ host: 'localhost', port: 9996 }] } }], enableDetailedLogging: false, diff --git a/test/test.connect-disconnect-cleanup.node.ts b/test/test.connect-disconnect-cleanup.node.ts index a5f6fe9..551e92c 100644 --- a/test/test.connect-disconnect-cleanup.node.ts +++ b/test/test.connect-disconnect-cleanup.node.ts @@ -18,10 +18,10 @@ tap.test('should handle clients that connect and immediately disconnect without match: { ports: 8560 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 9999 // Non-existent port - } + }] } }] }); @@ -173,10 +173,10 @@ tap.test('should handle clients that error during connection', async () => { match: { ports: 8561 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 9999 - } + }] } }] }); diff --git a/test/test.connection-cleanup-comprehensive.node.ts b/test/test.connection-cleanup-comprehensive.node.ts index bc9593e..e59e792 100644 --- a/test/test.connection-cleanup-comprehensive.node.ts +++ b/test/test.connection-cleanup-comprehensive.node.ts @@ -20,10 +20,10 @@ tap.test('comprehensive connection cleanup test - all scenarios', async () => { match: { ports: 8570 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 9999 // Non-existent port - } + }] } }, { @@ -31,10 +31,10 @@ tap.test('comprehensive connection cleanup test - all scenarios', async () => { match: { ports: 8571 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 9999 // Non-existent port - }, + }], tls: { mode: 'passthrough' } @@ -215,10 +215,10 @@ tap.test('comprehensive connection cleanup test - all scenarios', async () => { action: { type: 'forward', forwardingEngine: 'nftables', - target: { + targets: [{ host: 'localhost', port: 9999 - } + }] } }] }); diff --git a/test/test.connection-forwarding.ts b/test/test.connection-forwarding.ts index 7f8ef6d..cfee048 100644 --- a/test/test.connection-forwarding.ts +++ b/test/test.connection-forwarding.ts @@ -65,10 +65,10 @@ tap.test('should forward TCP connections correctly', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: '127.0.0.1', port: 7001, - }, + }], }, }, ], @@ -118,10 +118,10 @@ tap.test('should handle TLS passthrough correctly', async () => { tls: { mode: 'passthrough', }, - target: { + targets: [{ host: '127.0.0.1', port: 7002, - }, + }], }, }, ], @@ -179,10 +179,10 @@ tap.test('should handle SNI-based forwarding', async () => { tls: { mode: 'passthrough', }, - target: { + targets: [{ host: '127.0.0.1', port: 7002, - }, + }], }, }, { @@ -197,10 +197,10 @@ tap.test('should handle SNI-based forwarding', async () => { tls: { mode: 'passthrough', }, - target: { + targets: [{ host: '127.0.0.1', port: 7002, - }, + }], }, }, ], diff --git a/test/test.connection-limits.node.ts b/test/test.connection-limits.node.ts index 2c5c4f2..5999c2c 100644 --- a/test/test.connection-limits.node.ts +++ b/test/test.connection-limits.node.ts @@ -90,10 +90,10 @@ tap.test('Setup test environment', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: TEST_SERVER_PORT - } + }] }, security: { maxConnections: 5 // Low limit for testing @@ -198,10 +198,10 @@ tap.test('HttpProxy per-IP validation', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: TEST_SERVER_PORT - }, + }], tls: { mode: 'terminate' } diff --git a/test/test.fix-verification.ts b/test/test.fix-verification.ts index 48f25eb..be2446b 100644 --- a/test/test.fix-verification.ts +++ b/test/test.fix-verification.ts @@ -9,7 +9,7 @@ tap.test('should verify certificate manager callback is preserved on updateRoute match: { ports: [18443], domains: ['test.local'] }, action: { type: 'forward', - target: { host: 'localhost', port: 3000 }, + targets: [{ host: 'localhost', port: 3000 }], tls: { mode: 'terminate', certificate: 'auto', @@ -63,7 +63,7 @@ tap.test('should verify certificate manager callback is preserved on updateRoute match: { ports: [18444], domains: ['test2.local'] }, action: { type: 'forward', - target: { host: 'localhost', port: 3001 }, + targets: [{ host: 'localhost', port: 3001 }], tls: { mode: 'terminate', certificate: 'auto', diff --git a/test/test.forwarding-fix-verification.ts b/test/test.forwarding-fix-verification.ts index 83f2258..20f6d80 100644 --- a/test/test.forwarding-fix-verification.ts +++ b/test/test.forwarding-fix-verification.ts @@ -37,7 +37,7 @@ tap.test('regular forward route should work correctly', async () => { match: { ports: 7890 }, action: { type: 'forward', - target: { host: 'localhost', port: 6789 } + targets: [{ host: 'localhost', port: 6789 }] } }] }); @@ -106,7 +106,7 @@ tap.skip.test('NFTables forward route should not terminate connections (requires action: { type: 'forward', forwardingEngine: 'nftables', - target: { host: 'localhost', port: 6789 } + targets: [{ host: 'localhost', port: 6789 }] } }] }); diff --git a/test/test.forwarding-regression.ts b/test/test.forwarding-regression.ts index 103087a..cb20bf2 100644 --- a/test/test.forwarding-regression.ts +++ b/test/test.forwarding-regression.ts @@ -39,10 +39,10 @@ tap.test('forward connections should not be immediately closed', async (t) => { }, action: { type: 'forward', - target: { + targets: [{ host: '127.0.0.1', port: 9090, - }, + }], }, }, ], diff --git a/test/test.forwarding.ts b/test/test.forwarding.ts index d5d89bd..3429866 100644 --- a/test/test.forwarding.ts +++ b/test/test.forwarding.ts @@ -39,7 +39,7 @@ tap.test('Route Helpers - Create HTTP routes', async () => { const route = helpers.httpOnly('example.com', { host: 'localhost', port: 3000 }); expect(route.action.type).toEqual('forward'); expect(route.match.domains).toEqual('example.com'); - expect(route.action.target).toEqual({ host: 'localhost', port: 3000 }); + expect(route.action.targets?.[0]).toEqual({ host: 'localhost', port: 3000 }); }); tap.test('Route Helpers - Create HTTPS terminate to HTTP routes', async () => { diff --git a/test/test.http-fix-unit.ts b/test/test.http-fix-unit.ts index 2839f9a..80e7a3b 100644 --- a/test/test.http-fix-unit.ts +++ b/test/test.http-fix-unit.ts @@ -20,7 +20,7 @@ tap.test('should forward non-TLS connections on HttpProxy ports', async (tapTest match: { ports: testPort }, action: { type: 'forward', - target: { host: 'localhost', port: 8181 } + targets: [{ host: 'localhost', port: 8181 }] } }] }; @@ -81,7 +81,7 @@ tap.test('should use direct connection for non-HttpProxy ports', async (tapTest) match: { ports: 8080 }, // Not in useHttpProxy action: { type: 'forward', - target: { host: 'localhost', port: 8181 } + targets: [{ host: 'localhost', port: 8181 }] } }] }; @@ -142,7 +142,7 @@ tap.test('should handle ACME HTTP-01 challenges on port 80 with HttpProxy', asyn }, action: { type: 'forward', - target: { host: 'localhost', port: 8080 } + targets: [{ host: 'localhost', port: 8080 }] } }] }; diff --git a/test/test.http-fix-verification.ts b/test/test.http-fix-verification.ts index 98d5197..2a8a07d 100644 --- a/test/test.http-fix-verification.ts +++ b/test/test.http-fix-verification.ts @@ -14,7 +14,7 @@ tap.test('should detect and forward non-TLS connections on useHttpProxy ports', match: { ports: 8080 }, action: { type: 'forward', - target: { host: 'localhost', port: 8181 } + targets: [{ host: 'localhost', port: 8181 }] } }] }; @@ -140,7 +140,7 @@ tap.test('should handle TLS connections normally', async (tapTest) => { match: { ports: 443 }, action: { type: 'forward', - target: { host: 'localhost', port: 8443 }, + targets: [{ host: 'localhost', port: 8443 }], tls: { mode: 'terminate' } } }] diff --git a/test/test.http-forwarding-fix.ts b/test/test.http-forwarding-fix.ts index 5da6b50..d473e75 100644 --- a/test/test.http-forwarding-fix.ts +++ b/test/test.http-forwarding-fix.ts @@ -17,7 +17,7 @@ tap.test('should detect and forward non-TLS connections on HttpProxy ports', asy match: { ports: 8081 }, action: { type: 'forward', - target: { host: 'localhost', port: 8181 } + targets: [{ host: 'localhost', port: 8181 }] } }] }); @@ -120,7 +120,7 @@ tap.test('should properly detect non-TLS connections on HttpProxy ports', async }, action: { type: 'forward', - target: { host: 'localhost', port: targetPort } + targets: [{ host: 'localhost', port: targetPort }] } }] }); diff --git a/test/test.http-port8080-forwarding.ts b/test/test.http-port8080-forwarding.ts index 7e9da39..8116e2b 100644 --- a/test/test.http-port8080-forwarding.ts +++ b/test/test.http-port8080-forwarding.ts @@ -42,7 +42,7 @@ tap.test('should forward HTTP connections on port 8080', async (tapTest) => { }, action: { type: 'forward', - target: { host: 'localhost', port: targetPort } + targets: [{ host: 'localhost', port: targetPort }] } }] }); @@ -131,7 +131,7 @@ tap.test('should handle basic HTTP request forwarding', async (tapTest) => { }, action: { type: 'forward', - target: { host: 'localhost', port: targetPort } + targets: [{ host: 'localhost', port: targetPort }] } }] }); diff --git a/test/test.http-port8080-simple.ts b/test/test.http-port8080-simple.ts index fe59859..05a0a49 100644 --- a/test/test.http-port8080-simple.ts +++ b/test/test.http-port8080-simple.ts @@ -67,7 +67,7 @@ tap.test('should handle ACME challenges on port 8080 with improved port binding }, action: { type: 'forward', - target: { host: 'localhost', port: targetPort }, + targets: [{ host: 'localhost', port: targetPort }], tls: { mode: 'terminate', certificate: 'auto' // Use ACME for certificate @@ -83,7 +83,7 @@ tap.test('should handle ACME challenges on port 8080 with improved port binding }, action: { type: 'forward', - target: { host: 'localhost', port: targetPort } + targets: [{ host: 'localhost', port: targetPort }] } } ], @@ -191,7 +191,7 @@ tap.test('should handle ACME challenges on port 8080 with improved port binding }, action: { type: 'forward' as const, - target: { host: 'localhost', port: targetPort } + targets: [{ host: 'localhost', port: targetPort }] } } ]; diff --git a/test/test.httpproxy.function-targets.ts b/test/test.httpproxy.function-targets.ts index a5c1ec1..926e489 100644 --- a/test/test.httpproxy.function-targets.ts +++ b/test/test.httpproxy.function-targets.ts @@ -95,10 +95,10 @@ tap.test('should support static host/port routes', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: serverPort - } + }] } } ]; @@ -135,13 +135,13 @@ tap.test('should support function-based host', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: (context: IRouteContext) => { // Return localhost always in this test return 'localhost'; }, port: serverPort - } + }] } } ]; @@ -178,13 +178,13 @@ tap.test('should support function-based port', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: (context: IRouteContext) => { // Return test server port return serverPort; } - } + }] } } ]; @@ -221,14 +221,14 @@ tap.test('should support function-based host AND port', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: (context: IRouteContext) => { return 'localhost'; }, port: (context: IRouteContext) => { return serverPort; } - } + }] } } ]; @@ -265,7 +265,7 @@ tap.test('should support context-based routing with path', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: (context: IRouteContext) => { // Use path to determine host if (context.path?.startsWith('/api')) { @@ -275,7 +275,7 @@ tap.test('should support context-based routing with path', async () => { } }, port: serverPort - } + }] } } ]; diff --git a/test/test.keepalive-support.node.ts b/test/test.keepalive-support.node.ts index a4573b1..0c5976c 100644 --- a/test/test.keepalive-support.node.ts +++ b/test/test.keepalive-support.node.ts @@ -40,7 +40,7 @@ tap.test('keepalive support - verify keepalive connections are properly handled' match: { ports: 8590 }, action: { type: 'forward', - target: { host: 'localhost', port: 9998 } + targets: [{ host: 'localhost', port: 9998 }] } }], keepAlive: true, @@ -117,7 +117,7 @@ tap.test('keepalive support - verify keepalive connections are properly handled' match: { ports: 8591 }, action: { type: 'forward', - target: { host: 'localhost', port: 9998 } + targets: [{ host: 'localhost', port: 9998 }] } }], keepAlive: true, @@ -178,7 +178,7 @@ tap.test('keepalive support - verify keepalive connections are properly handled' match: { ports: 8592 }, action: { type: 'forward', - target: { host: 'localhost', port: 9998 } + targets: [{ host: 'localhost', port: 9998 }] } }], keepAlive: true, diff --git a/test/test.long-lived-connections.ts b/test/test.long-lived-connections.ts index e8ab9f6..1a6f449 100644 --- a/test/test.long-lived-connections.ts +++ b/test/test.long-lived-connections.ts @@ -39,10 +39,10 @@ tap.test('setup test environment', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 9876 - } + }] // No TLS configuration - just plain TCP forwarding } }], diff --git a/test/test.metrics-new.ts b/test/test.metrics-new.ts index dd2d77b..a95d844 100644 --- a/test/test.metrics-new.ts +++ b/test/test.metrics-new.ts @@ -36,10 +36,10 @@ tap.test('should create SmartProxy instance with new metrics', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: echoServerPort - }, + }], tls: { mode: 'passthrough' } diff --git a/test/test.nftables-forwarding.ts b/test/test.nftables-forwarding.ts index b15232e..fc4bdb5 100644 --- a/test/test.nftables-forwarding.ts +++ b/test/test.nftables-forwarding.ts @@ -34,10 +34,10 @@ tap.skip.test('NFTables forwarding should not terminate connections (requires ro action: { type: 'forward', forwardingEngine: 'nftables', - target: { + targets: [{ host: '127.0.0.1', port: 8001, - }, + }], }, }, // Also add regular forwarding route for comparison @@ -49,10 +49,10 @@ tap.skip.test('NFTables forwarding should not terminate connections (requires ro }, action: { type: 'forward', - target: { + targets: [{ host: '127.0.0.1', port: 8001, - }, + }], }, }, ], diff --git a/test/test.nftables-manager.ts b/test/test.nftables-manager.ts index d838bbb..c381e25 100644 --- a/test/test.nftables-manager.ts +++ b/test/test.nftables-manager.ts @@ -42,10 +42,10 @@ const sampleRoute: IRouteConfig = { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 8000 - }, + }], forwardingEngine: 'nftables', nftables: { protocol: 'tcp', @@ -115,10 +115,10 @@ tap.skip.test('NFTablesManager route updating test', async () => { ...sampleRoute, action: { ...sampleRoute.action, - target: { + targets: [{ host: 'localhost', port: 9000 // Different port - }, + }], nftables: { ...sampleRoute.action.nftables, protocol: 'all' // Different protocol @@ -147,10 +147,10 @@ tap.skip.test('NFTablesManager route deprovisioning test', async () => { ...sampleRoute, action: { ...sampleRoute.action, - target: { + targets: [{ host: 'localhost', port: 9000 // Different port from original test - }, + }], nftables: { ...sampleRoute.action.nftables, protocol: 'all' // Different protocol from original test diff --git a/test/test.nftables-status.ts b/test/test.nftables-status.ts index cbce6c9..d5de843 100644 --- a/test/test.nftables-status.ts +++ b/test/test.nftables-status.ts @@ -91,7 +91,7 @@ testFn('SmartProxy getNfTablesStatus functionality', async () => { match: { ports: 3004 }, action: { type: 'forward', - target: { host: 'localhost', port: 3005 } + targets: [{ host: 'localhost', port: 3005 }] } } ] diff --git a/test/test.port-forwarding-fix.ts b/test/test.port-forwarding-fix.ts index b88deba..fc0f755 100644 --- a/test/test.port-forwarding-fix.ts +++ b/test/test.port-forwarding-fix.ts @@ -29,7 +29,7 @@ tap.test('port forwarding should not immediately close connections', async (tool match: { ports: 9999 }, action: { type: 'forward', - target: { host: 'localhost', port: 8888 } + targets: [{ host: 'localhost', port: 8888 }] } }] }); @@ -63,7 +63,7 @@ tap.test('TLS passthrough should work correctly', async () => { action: { type: 'forward', tls: { mode: 'passthrough' }, - target: { host: 'localhost', port: 443 } + targets: [{ host: 'localhost', port: 443 }] } }] }); diff --git a/test/test.port-mapping.ts b/test/test.port-mapping.ts index b34c9fc..5ecd748 100644 --- a/test/test.port-mapping.ts +++ b/test/test.port-mapping.ts @@ -214,12 +214,12 @@ tap.test('should handle errors in port mapping functions', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: () => { throw new Error('Test error in port mapping function'); } - } + }] }, name: 'Error Route' }; diff --git a/test/test.port80-management.node.ts b/test/test.port80-management.node.ts index fece240..ba413e6 100644 --- a/test/test.port80-management.node.ts +++ b/test/test.port80-management.node.ts @@ -21,7 +21,7 @@ tap.test('should not double-register port 80 when user route and ACME use same p }, action: { type: 'forward' as const, - target: { host: 'localhost', port: 3000 } + targets: [{ host: 'localhost', port: 3000 }] } }, { @@ -31,7 +31,7 @@ tap.test('should not double-register port 80 when user route and ACME use same p }, action: { type: 'forward' as const, - target: { host: 'localhost', port: 3001 }, + targets: [{ host: 'localhost', port: 3001 }], tls: { mode: 'terminate' as const, certificate: 'auto' as const @@ -153,7 +153,7 @@ tap.test('should handle ACME on different port than user routes', async (tools) }, action: { type: 'forward' as const, - target: { host: 'localhost', port: 3000 } + targets: [{ host: 'localhost', port: 3000 }] } }, { @@ -163,7 +163,7 @@ tap.test('should handle ACME on different port than user routes', async (tools) }, action: { type: 'forward' as const, - target: { host: 'localhost', port: 3001 }, + targets: [{ host: 'localhost', port: 3001 }], tls: { mode: 'terminate' as const, certificate: 'auto' as const diff --git a/test/test.proxy-chain-cleanup.node.ts b/test/test.proxy-chain-cleanup.node.ts index 9fcce63..985bf1e 100644 --- a/test/test.proxy-chain-cleanup.node.ts +++ b/test/test.proxy-chain-cleanup.node.ts @@ -15,10 +15,10 @@ tap.test('setup two smartproxies in a chain configuration', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'httpbin.org', port: 443 - } + }] } } ], @@ -45,10 +45,10 @@ tap.test('setup two smartproxies in a chain configuration', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 8002 - }, + }], sendProxyProtocol: true } } diff --git a/test/test.proxy-chain-simple.node.ts b/test/test.proxy-chain-simple.node.ts index 286b9c9..c8c6222 100644 --- a/test/test.proxy-chain-simple.node.ts +++ b/test/test.proxy-chain-simple.node.ts @@ -32,10 +32,10 @@ tap.test('simple proxy chain test - identify connection accumulation', async () match: { ports: 8591 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 9998 // Backend that closes immediately - } + }] } }] }); @@ -50,10 +50,10 @@ tap.test('simple proxy chain test - identify connection accumulation', async () match: { ports: 8590 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 8591 // Forward to proxy2 - } + }] } }] }); diff --git a/test/test.proxy-chaining-accumulation.node.ts b/test/test.proxy-chaining-accumulation.node.ts index 38ee9b1..5828688 100644 --- a/test/test.proxy-chaining-accumulation.node.ts +++ b/test/test.proxy-chaining-accumulation.node.ts @@ -19,10 +19,10 @@ tap.test('should handle proxy chaining without connection accumulation', async ( match: { ports: 8581 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 9999 // Non-existent backend - } + }] } }] }); @@ -37,10 +37,10 @@ tap.test('should handle proxy chaining without connection accumulation', async ( match: { ports: 8580 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 8581 // Forward to proxy2 - } + }] } }] }); @@ -270,10 +270,10 @@ tap.test('should handle proxy chain with HTTP traffic', async () => { match: { ports: 8583 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 9999 // Non-existent backend - } + }] } }] }); @@ -289,10 +289,10 @@ tap.test('should handle proxy chain with HTTP traffic', async () => { match: { ports: 8582 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 8583 // Forward to proxy2 - } + }] } }] }); diff --git a/test/test.rapid-retry-cleanup.node.ts b/test/test.rapid-retry-cleanup.node.ts index 35578a6..9528331 100644 --- a/test/test.rapid-retry-cleanup.node.ts +++ b/test/test.rapid-retry-cleanup.node.ts @@ -19,10 +19,10 @@ tap.test('should handle rapid connection retries without leaking connections', a match: { ports: 8550 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 9999 // Non-existent port to force connection failures - } + }] } }] }); diff --git a/test/test.route-callback-simple.ts b/test/test.route-callback-simple.ts index 4099a73..ec94c12 100644 --- a/test/test.route-callback-simple.ts +++ b/test/test.route-callback-simple.ts @@ -17,7 +17,7 @@ tap.test('should set update routes callback on certificate manager', async () => }, action: { type: 'forward', - target: { host: 'localhost', port: 3000 }, + targets: [{ host: 'localhost', port: 3000 }], tls: { mode: 'terminate', certificate: 'auto', @@ -95,7 +95,7 @@ tap.test('should set update routes callback on certificate manager', async () => }, action: { type: 'forward', - target: { host: 'localhost', port: 3001 }, + targets: [{ host: 'localhost', port: 3001 }], tls: { mode: 'terminate', certificate: 'auto', diff --git a/test/test.route-security-integration.ts b/test/test.route-security-integration.ts index e7889f3..3049c37 100644 --- a/test/test.route-security-integration.ts +++ b/test/test.route-security-integration.ts @@ -28,10 +28,10 @@ tap.test('route security should block connections from unauthorized IPs', async }, action: { type: 'forward', - target: { + targets: [{ host: '127.0.0.1', port: 9990 - } + }] }, security: { // Only allow a non-existent IP @@ -142,10 +142,10 @@ tap.test('route security with block list should work', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: '127.0.0.1', port: 9992 - } + }] }, security: { // Security at route level, not action level ipBlockList: ['127.0.0.1', '::1', '::ffff:127.0.0.1'] @@ -234,10 +234,10 @@ tap.test('route without security should allow all connections', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: '127.0.0.1', port: 9994 - } + }] } // No security defined }]; diff --git a/test/test.route-security-unit.ts b/test/test.route-security-unit.ts index 2fde895..f7c942e 100644 --- a/test/test.route-security-unit.ts +++ b/test/test.route-security-unit.ts @@ -10,10 +10,10 @@ tap.test('route security should be correctly configured', async () => { }, action: { type: 'forward' as const, - target: { + targets: [{ host: '127.0.0.1', port: 8991 - }, + }], security: { ipAllowList: ['192.168.1.1'], ipBlockList: ['10.0.0.1'] diff --git a/test/test.route-security.ts b/test/test.route-security.ts index 3ad66a0..47f6e39 100644 --- a/test/test.route-security.ts +++ b/test/test.route-security.ts @@ -26,10 +26,10 @@ tap.test('route-specific security should be enforced', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: '127.0.0.1', port: 8877 - } + }] }, security: { ipAllowList: ['127.0.0.1', '::1', '::ffff:127.0.0.1'] @@ -108,10 +108,10 @@ tap.test('route-specific IP block list should be enforced', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: '127.0.0.1', port: 8879 - } + }] }, security: { ipAllowList: ['0.0.0.0/0', '::/0'], // Allow all IPs @@ -215,10 +215,10 @@ tap.test('routes without security should allow all connections', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: '127.0.0.1', port: 8881 - } + }] // No security section - should allow all } }]; diff --git a/test/test.route-update-callback.node.ts b/test/test.route-update-callback.node.ts index 21cc591..1a309a4 100644 --- a/test/test.route-update-callback.node.ts +++ b/test/test.route-update-callback.node.ts @@ -13,10 +13,10 @@ const createRoute = (id: number, domain: string, port: number = 8443) => ({ }, action: { type: 'forward' as const, - target: { + targets: [{ host: 'localhost', port: 3000 + id - }, + }], tls: { mode: 'terminate' as const, certificate: 'auto' as const, @@ -209,10 +209,10 @@ tap.test('should handle route updates when cert manager is not initialized', asy }, action: { type: 'forward' as const, - target: { + targets: [{ host: 'localhost', port: 3000 - } + }] } }] }); diff --git a/test/test.router.ts b/test/test.router.ts index 932cb01..8df87de 100644 --- a/test/test.router.ts +++ b/test/test.router.ts @@ -37,10 +37,10 @@ function createRouteConfig( }, action: { type: 'forward', - target: { + targets: [{ host: destinationIp, port: destinationPort - } + }] } }; } diff --git a/test/test.smartacme-integration.ts b/test/test.smartacme-integration.ts index abab35f..198967e 100644 --- a/test/test.smartacme-integration.ts +++ b/test/test.smartacme-integration.ts @@ -15,10 +15,10 @@ tap.test('should create a SmartCertManager instance', async () => { }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 3000 - }, + }], tls: { mode: 'terminate', certificate: 'auto', diff --git a/test/test.stuck-connection-cleanup.node.ts b/test/test.stuck-connection-cleanup.node.ts index 1a6356c..6b01f5b 100644 --- a/test/test.stuck-connection-cleanup.node.ts +++ b/test/test.stuck-connection-cleanup.node.ts @@ -30,7 +30,7 @@ tap.test('stuck connection cleanup - verify connections to hanging backends are match: { ports: 8589 }, action: { type: 'forward', - target: { host: 'localhost', port: 9997 } + targets: [{ host: 'localhost', port: 9997 }] } }], keepAlive: true, diff --git a/test/test.websocket-keepalive.node.ts b/test/test.websocket-keepalive.node.ts index c1bf605..f4183d7 100644 --- a/test/test.websocket-keepalive.node.ts +++ b/test/test.websocket-keepalive.node.ts @@ -17,7 +17,7 @@ tap.test('websocket keep-alive settings for SNI passthrough', async (tools) => { match: { ports: 8443, domains: 'test.local' }, action: { type: 'forward', - target: { host: 'localhost', port: 9443 }, + targets: [{ host: 'localhost', port: 9443 }], tls: { mode: 'passthrough' } } } @@ -108,7 +108,7 @@ tap.test('long-lived connection survival test', async (tools) => { match: { ports: 8444 }, action: { type: 'forward', - target: { host: 'localhost', port: 9444 } + targets: [{ host: 'localhost', port: 9444 }] } } ] diff --git a/test/test.zombie-connection-cleanup.node.ts b/test/test.zombie-connection-cleanup.node.ts index 53a5bfe..7e8ceb6 100644 --- a/test/test.zombie-connection-cleanup.node.ts +++ b/test/test.zombie-connection-cleanup.node.ts @@ -52,10 +52,10 @@ tap.test('zombie connection cleanup - verify inactivity check detects and cleans match: { ports: 8591 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 9998 - } + }] } }] }); @@ -71,10 +71,10 @@ tap.test('zombie connection cleanup - verify inactivity check detects and cleans match: { ports: 8590 }, action: { type: 'forward', - target: { + targets: [{ host: 'localhost', port: 8591 - } + }] } }] });