serverus/tests/helpers.ts

67 lines
1.7 KiB
TypeScript

import { SERVER, SERVER_OPTIONS } from '../server.ts';
const BASE_PORT: number = 50_000;
const MAX_PORT_OFFSET: number = 10_000;
let current_port_offset = 0;
function get_next_free_port(): number {
let free_port: number | undefined = undefined;
let attempts = 0;
do {
const port_to_try: number = BASE_PORT + (current_port_offset++ % MAX_PORT_OFFSET);
try {
Deno.listen({ port: port_to_try }).close();
free_port = port_to_try;
} catch (error) {
if (!(error instanceof Deno.errors.AddrInUse)) {
throw error;
}
}
++attempts;
if (attempts % MAX_PORT_OFFSET === 0) {
console.warn(`Tried all ports at least once while trying to locate a free one, something wrong?`);
}
} while (!free_port);
return free_port;
}
/**
* Interface defining the configuration for an ephemeral server
* @property {string} hostname - hostname bound to, default: 'localhost'
* @property {number} port - port bound to, default: next free port
* @property {SERVER} server - server instance
*/
export interface EPHEMERAL_SERVER {
hostname: string;
port: number;
server: SERVER;
}
/**
* Gets an ephemeral Serverus SERVER on an unused port.
*
* @param options Optional SERVER_OPTIONS
* @returns A LISTEN_SERVER_SETUP object with information and a reference to the server
*/
export async function get_ephemeral_listen_server(options?: SERVER_OPTIONS): Promise<EPHEMERAL_SERVER> {
const server_options = {
...{
hostname: 'localhost',
port: get_next_free_port()
},
...(options ?? {})
};
const server = new SERVER(server_options);
const ephemeral_server: EPHEMERAL_SERVER = {
hostname: server_options.hostname,
port: server_options.port,
server: await server.start()
};
return ephemeral_server;
}