import { tap, expect } from '@git.zone/tstest/tapbundle'; import { buildRateLimitRule, buildPerIpRateLimitRule, buildConnectionRateRule, } from '../ts/nft.rulebuilder.ratelimit.js'; tap.test('should build global rate limit rule', async () => { const rules = buildRateLimitRule('mytable', 'ip', { port: 80, protocol: 'tcp', rate: '100/second', }); expect(rules.length).toEqual(1); expect(rules[0]).toInclude('limit rate over 100/second'); expect(rules[0]).toInclude('tcp dport 80'); expect(rules[0]).toInclude('drop'); }); tap.test('should build rate limit with burst', async () => { const rules = buildRateLimitRule('mytable', 'ip', { port: 8080, rate: '50/second', burst: 20, }); expect(rules[0]).toInclude('burst 20 packets'); }); tap.test('should build rate limit with custom action', async () => { const rules = buildRateLimitRule('mytable', 'ip', { port: 80, rate: '100/second', action: 'reject', }); expect(rules[0]).toInclude('reject'); expect(rules[0]).not.toInclude('drop'); }); tap.test('should build per-IP rate limit using meters', async () => { const rules = buildRateLimitRule('mytable', 'ip', { port: 80, protocol: 'tcp', rate: '10/second', perSourceIP: true, }); expect(rules.length).toEqual(1); expect(rules[0]).toInclude('meter'); expect(rules[0]).toInclude('ip saddr'); expect(rules[0]).toInclude('limit rate over 10/second'); }); tap.test('should build per-IP rate limit via convenience function', async () => { const rules = buildPerIpRateLimitRule('mytable', 'ip', { port: 443, rate: '50/second', }); expect(rules[0]).toInclude('meter'); expect(rules[0]).toInclude('ip saddr'); }); tap.test('should build rate limit on custom chain', async () => { const rules = buildRateLimitRule('mytable', 'ip', { port: 80, rate: '100/second', chain: 'forward', }); expect(rules[0]).toInclude('mytable forward'); }); tap.test('should build connection rate rule', async () => { const rules = buildConnectionRateRule('mytable', 'ip', { port: 22, protocol: 'tcp', rate: '5/second', }); expect(rules.length).toEqual(1); expect(rules[0]).toInclude('ct state new'); expect(rules[0]).toInclude('tcp dport 22'); expect(rules[0]).toInclude('limit rate over 5/second'); expect(rules[0]).toInclude('drop'); }); tap.test('should build per-IP connection rate rule', async () => { const rules = buildConnectionRateRule('mytable', 'ip', { port: 80, rate: '10/second', perSourceIP: true, }); expect(rules[0]).toInclude('meter connrate'); expect(rules[0]).toInclude('ip saddr'); expect(rules[0]).toInclude('ct state new'); }); tap.test('should build rate limit for both protocols', async () => { const rules = buildRateLimitRule('mytable', 'ip', { port: 53, protocol: 'both', rate: '100/second', }); expect(rules.length).toEqual(2); expect(rules[0]).toInclude('tcp'); expect(rules[1]).toInclude('udp'); }); export default tap.start();