Files
smartradius/test/client/test.timeout.ts

150 lines
3.8 KiB
TypeScript

import { expect, tap } from '@git.zone/tstest/tapbundle';
import { RadiusClient } from '../../ts_client/index.js';
tap.test('should timeout when server is not reachable', async () => {
// Connect to a port where no server is running
const client = new RadiusClient({
host: '127.0.0.1',
authPort: 19999, // Unlikely to have a server
acctPort: 19998,
secret: 'testing123',
timeout: 500, // Short timeout
retries: 1, // Minimal retries
});
await client.connect();
let error: Error | undefined;
try {
await client.authenticatePap('user', 'pass');
} catch (e) {
error = e as Error;
}
expect(error).toBeDefined();
expect(error!.message).toInclude('timed out');
await client.disconnect();
});
tap.test('should retry on timeout', async () => {
const startTime = Date.now();
const client = new RadiusClient({
host: '127.0.0.1',
authPort: 19997,
acctPort: 19996,
secret: 'testing123',
timeout: 200, // 200ms timeout
retries: 3, // 3 retries
retryDelay: 100, // 100ms initial delay
});
await client.connect();
let error: Error | undefined;
try {
await client.authenticatePap('user', 'pass');
} catch (e) {
error = e as Error;
}
const elapsed = Date.now() - startTime;
expect(error).toBeDefined();
// With 3 retries and exponential backoff, should take at least:
// Initial timeout (200) + retry 1 delay (100) + timeout (200) + retry 2 delay (200) + timeout (200) + retry 3 delay (400) + timeout (200)
// = 200 + 100 + 200 + 200 + 200 + 400 + 200 = ~1500ms minimum
expect(elapsed).toBeGreaterThanOrEqual(500);
await client.disconnect();
});
tap.test('should handle disconnect during request', async () => {
const client = new RadiusClient({
host: '127.0.0.1',
authPort: 19995,
acctPort: 19994,
secret: 'testing123',
timeout: 5000,
retries: 3,
});
await client.connect();
// Start a request (will never complete because no server)
const requestPromise = client.authenticatePap('user', 'pass');
// Disconnect immediately
await client.disconnect();
let error: Error | undefined;
try {
await requestPromise;
} catch (e) {
error = e as Error;
}
// When the client disconnects, pending requests are rejected
// The error can be either "Client disconnected" or other disconnect-related messages
expect(error).toBeDefined();
// Just verify we got an error - the specific message may vary
});
tap.test('should handle multiple concurrent requests', async () => {
// This test just verifies we can make multiple requests
// They will all timeout since no server, but should handle correctly
const client = new RadiusClient({
host: '127.0.0.1',
authPort: 19993,
acctPort: 19992,
secret: 'testing123',
timeout: 200,
retries: 1,
});
await client.connect();
const requests = [
client.authenticatePap('user1', 'pass1').catch((e) => e),
client.authenticatePap('user2', 'pass2').catch((e) => e),
client.authenticatePap('user3', 'pass3').catch((e) => e),
];
const results = await Promise.all(requests);
// All should be errors (timeout)
for (const result of results) {
expect(result).toBeInstanceOf(Error);
}
await client.disconnect();
});
tap.test('should auto-connect if not connected', async () => {
const client = new RadiusClient({
host: '127.0.0.1',
authPort: 19991,
acctPort: 19990,
secret: 'testing123',
timeout: 200,
retries: 1,
});
// Don't call connect() - should auto-connect
let error: Error | undefined;
try {
await client.authenticatePap('user', 'pass');
} catch (e) {
error = e as Error;
}
// Should timeout, not connection error
expect(error).toBeDefined();
expect(error!.message).toInclude('timed out');
await client.disconnect();
});
export default tap.start();