bigbluebutton-Github/bigbluebutton-tests/playwright/connectionFailure/util.js

58 lines
2.5 KiB
JavaScript

const util = require('node:util');
const exec = util.promisify(require('node:child_process').exec);
const process = require('node:process');
const parameters = require('../core/parameters.js');
// Hostname of BBB server that we're going to break connections to
const hostname = new URL(parameters.server).hostname;
// Parse a line of output from the 'ss' program into an object
// with fields local (local IP address and TCP port), remote
// (remote address and port) and pid (localhost process ID)
function parseline(line) {
const fields = line.split(/\s+/);
// These two are like '192.168.8.1:59164'
const local = fields[3].split(/:/);
const remote = fields[4].split(/:/);
// This one is like 'users:(("chrome",pid=3346964,fd=118))'
const process = fields[5];
const pid = parseInt(process.match(/pid=([0-9]+),/)[1]);
return { local: { ip: local[0], port: parseInt(local[1]) },
remote: { ip: remote[0], port: parseInt(remote[1]) },
pid: pid };
}
// return an array of such structures for the current process
// and all of its subprocesses that connect to a given host
async function getCurrentTCPSessions() {
// First, get the process IDs of all of our subprocesses, which include the test browser(s).
// The process IDs will appear in parenthesis after the command names in stdout.
const { stdout } = await exec("pstree -pn " + process.pid);
const processIDs = stdout.matchAll(/\(([0-9]+)\)/g);
// Next, form a regular expression that matches all of those process IDs in ss's output format.
//
// The string matchAll method returned an iterator, which doesn't have a map method,
// so we convert the iterator to a list, then map it to a expression which matches the pid
// field in the output of ss, then join all the expressions together to form a regex.
const foundRE = new RegExp([...processIDs].map(x => 'pid=' + x[1]).join('|'));
// Now get all TCP sessions going to the target host
const { stdout: stdout2 } = await exec("ss -tpnH dst " + hostname);
// Extract those TCP sessions attached to our subprocesses, parse and and return them in an array.
return stdout2.split('\n').filter(x => foundRE.test(x)).map(x => parseline(x));
}
// takes an array of such structures and kills those TCP sessions
async function killTCPSessions(sessions) {
await exec('sudo ss -K dst ' + hostname + ' ' + sessions.map(x => 'sport = ' + x.local.port).join(' or '));
}
exports.getCurrentTCPSessions = getCurrentTCPSessions;
exports.killTCPSessions = killTCPSessions;