From 84130a64195f77013cf5690b23e8bd788a2607da Mon Sep 17 00:00:00 2001 From: Igor Lobanov Date: Tue, 4 Feb 2025 09:18:26 +0100 Subject: [PATCH] refactor network helper for e2e tests --- client/tests/helpers/network.ts | 74 ++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 24 deletions(-) diff --git a/client/tests/helpers/network.ts b/client/tests/helpers/network.ts index 33a797df..33c75970 100644 --- a/client/tests/helpers/network.ts +++ b/client/tests/helpers/network.ts @@ -1,4 +1,5 @@ import { networkInterfaces } from 'os'; +import type { NetworkInterfaceInfo } from 'node:os'; interface DHCPConfig { interfaceName: string; @@ -7,32 +8,57 @@ interface DHCPConfig { subnetMask: string; } +const DEFAULT_SUBNET_MASK = '255.255.255.0'; + +function checkIsIPv4(addr: NetworkInterfaceInfo): boolean { + return addr.family === 'IPv4' && !addr.internal; +} + +function calculateNetwork(ip: number[], mask: number[]): number[] { + // eslint-disable-next-line no-bitwise + return ip.map((octet, i) => octet & mask[i]); +} + +function calculateBroadcast(network: number[], mask: number[]): number[] { + // eslint-disable-next-line no-bitwise + return network.map((octet, i) => octet | (~mask[i] & 255)); +} + export function getDHCPConfig(): DHCPConfig { const interfaces = networkInterfaces(); - for (const [name, addresses] of Object.entries(interfaces)) { - const ipv4Address = addresses?.find((addr) => addr.family === 'IPv4' && !addr.internal); - if (ipv4Address) { - const ip = ipv4Address.address.split('.').map(Number); - const mask = ipv4Address.netmask?.split('.').map(Number) || [255, 255, 255, 0]; - - // Calculate network address - const network = ip.map((octet, i) => octet & mask[i]); - - // Calculate first and last usable addresses (excluding network and broadcast) - const rangeStart = [...network]; - rangeStart[3] = network[3] + 1; - - const broadcast = network.map((octet, i) => octet | (~mask[i] & 255)); - const rangeEnd = [...broadcast]; - rangeEnd[3] = broadcast[3] - 1; - return { - interfaceName: name, - rangeStart: rangeStart.join('.'), - rangeEnd: rangeEnd.join('.'), - subnetMask: ipv4Address.netmask || '255.255.255.0', - }; - } + const ipV4Interface = Object.entries(interfaces) + .map(([name, addresses]) => ({ + name, + addresses, + })) + .find((i) => { + return i.addresses?.some((addr) => checkIsIPv4(addr)); + }); + + if (!ipV4Interface) { + throw new Error('No suitable network interface found'); } - throw new Error('No suitable network interface found'); + + const ipv4Address = ipV4Interface.addresses.find((addr) => checkIsIPv4(addr)); + + const ip = ipv4Address.address.split('.').map(Number); + const mask = ipv4Address.netmask?.split('.').map(Number) || DEFAULT_SUBNET_MASK.split('.'); + + const network = calculateNetwork(ip, mask); + + // Calculate first and last usable addresses (excluding network and broadcast) + const rangeStart = [...network]; + rangeStart[3] = network[3] + 1; + + const broadcast = calculateBroadcast(network, mask); + const rangeEnd = [...broadcast]; + rangeEnd[3] = broadcast[3] - 1; + + return { + interfaceName: ipV4Interface.name, + rangeStart: rangeStart.join('.'), + rangeEnd: rangeEnd.join('.'), + subnetMask: ipv4Address.netmask || DEFAULT_SUBNET_MASK, + }; }