150 lines
3.8 KiB
TypeScript
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();
|