import { SmartProxy } from '../ts/proxies/smart-proxy/index.js'; import { expect, tap } from '@git.zone/tstest/tapbundle'; import * as child_process from 'child_process'; import { promisify } from 'util'; import type { IRouteConfig } from '../ts/proxies/smart-proxy/models/route-types.js'; const exec = promisify(child_process.exec); async function checkRootPrivileges(): Promise { try { const { stdout } = await exec('id -u'); return stdout.trim() === '0'; } catch (err) { return false; } } const isRoot = await checkRootPrivileges(); if (!isRoot) { console.log(''); console.log('========================================'); console.log('NFTables tests require root privileges'); console.log('Skipping NFTables integration tests'); console.log('========================================'); console.log(''); } const testFn = isRoot ? tap.test : tap.skip.test; testFn('NFTables integration tests', async () => { console.log('Running NFTables tests with root privileges'); const routes: IRouteConfig[] = [ { match: { ports: 9080 }, action: { type: 'forward', forwardingEngine: 'nftables', targets: [{ host: 'localhost', port: 8080 }], nftables: { protocol: 'tcp' } }, name: 'tcp-forward' }, { match: { ports: 5354 }, action: { type: 'forward', forwardingEngine: 'nftables', targets: [{ host: 'localhost', port: 5353 }], nftables: { protocol: 'udp' } }, name: 'udp-forward' }, { match: { ports: [{ from: 9000, to: 9100 }] }, action: { type: 'forward', forwardingEngine: 'nftables', targets: [{ host: 'localhost', port: 8080 }], nftables: { protocol: 'tcp' } }, name: 'port-range' } ]; const smartProxy = new SmartProxy({ enableDetailedLogging: true, routes }); await smartProxy.start(); console.log('SmartProxy started with NFTables routes'); const status = await smartProxy.getNfTablesStatus(); console.log('NFTables status:', JSON.stringify(status, null, 2)); expect(Object.keys(status).length).toEqual(routes.length); for (const routeStatus of Object.values(status)) { expect(routeStatus.active).toBeTrue(); expect(routeStatus.ruleCount.total).toBeGreaterThan(0); } await smartProxy.stop(); console.log('SmartProxy stopped'); const finalStatus = await smartProxy.getNfTablesStatus(); expect(Object.keys(finalStatus).length).toEqual(0); }); export default tap.start();