domotz-remote-pawn
Version:
Domotz Agent
177 lines (152 loc) • 7.14 kB
JavaScript
/** This file is part of Domotz Agent.
* Copyright (C) 2016 Domotz Ltd
*
* Domotz Agent is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Domotz Agent is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>.
**/
/**
*
* Created by Iacopo Papalini <ipapalini@domotz.com> on 10/09/15.
*/
const SPEED_TEST_SUITES = {
OOKLA: 'OOKLA',
NDT: 'NDT',
MLAB: 'MLAB',
FAST: 'FAST',
};
const MODULE_NAME = 'COMMANDS - COMMON_MODULE';
const DEFAULT_SPEED_TEST_SUITE = SPEED_TEST_SUITES.MLAB;
module.exports.factory = function (lodash, procUtils, dto, number, configuration, mlabSpeedTest, resourceLocator) {
var myConsole = resourceLocator.log.decorateLogs();
var command = process.env.DOMOTZ_BIN_DIR + '/domotz_web100clt -ll ' + '--disablemid --disablesfw -n ';
var bandWidthRegexp = /(\d+\.\d+) (.)b\/s/;
var dataRegexp = /^[^\:]+: +[0-9]+\.?[0-9]*/;
var errorRegexp = /^Connect\(\) for control socket failed/;
var ndt7SpeedTest = resourceLocator.networkTools.ndt7SpeedTest;
function gotUploadLine(item) {
return /^running [0-9]+s outbound test \(client to server\)[ \.\s]+/.test(item);
}
function gotDownloadLine(item) {
return /^running [0-9]+s inbound test \(server to client\)[ \.]+/.test(item);
}
function recordSpeedLine(item, str) {
var bandwidthValue = bandWidthRegexp.exec(item);
// conversion prefix to multiple (i.e. k => 1000)
var multiple = number.prefix2multiple(bandwidthValue[2]);
var speed = Math.floor(bandwidthValue[1] * multiple);
myConsole.verbose('Storing %s bandwidth %s => %s', str, item, speed, {});
return speed;
}
function parseOutput(server, data) {
myConsole.debug('Speed test successful');
var lines = data.toString().split(/\r?\n/);
var items = { raw: lines, server: server };
lines.forEach(function (item) {
// Check connect error
if (errorRegexp.test(item)) {
throw new Error('Processing NDT info for server ' + server.service.hostname + ' failed to connect:' + item);
}
if (gotUploadLine(item) && bandWidthRegexp.test(item)) {
items['speed.upload'] = recordSpeedLine(item, 'outbound');
} else if (gotDownloadLine(item) && bandWidthRegexp.test(item)) {
items['speed.download'] = recordSpeedLine(item, 'inbound');
} else if (dataRegexp.test(item)) {
var fields = item.split(': ');
if (fields.length !== 2) {
myConsole.warn('Fields malformed on item: %s', item, {});
} else {
items[fields[0]] = fields[1]; // putting the values to the corresponding item
myConsole.verbose('Storing field %s with value %s', fields[0], fields[1], {});
}
} else {
myConsole.verbose('Discard line: ' + item);
}
});
return items;
}
return {
performSpeedTest: function (server) {
var hostname = server.service.hostname;
myConsole.info('Launching slow web100clt on server %s', hostname);
myConsole.debug('Command: %s %s', command, hostname);
return procUtils
.exec(command + hostname)
.then(function (stdout) {
return parseOutput(server, stdout);
})
.catch(function (err) {
return { status: 500, message: err.message };
});
},
ndtInfoIntoDTO: function (ndtInfo) {
if (ndtInfo.rttsec) {
ndtInfo.rttsec *= 1000;
}
var map = {
'speed.upload': 'speed.upload',
'speed.download': 'speed.download',
rttsec: 'speed.rtt',
MaxRTT: 'speed.rttmax',
MinRTT: 'speed.rttmin',
server: 'server',
raw: 'raw',
};
return dto.mapArrayToDTO(ndtInfo, map);
},
filterItems: function (ndtInfo) {
var items = lodash.pick(ndtInfo, 'speed.upload', 'speed.download', 'rttsec', 'MinRTT', 'MaxRTT', 'server', 'raw');
items.rttmax = items.MaxRTT;
delete items.MaxRTT;
items.rttmin = items.MinRTT;
delete items.MinRTT;
items.rawdata = items.raw;
delete items.raw;
return items;
},
SPEED_TEST_SUITES: SPEED_TEST_SUITES,
getSpeedTestSuite: function getSpeedTestSuite(message) {
if (message && message.speed_test_suite) {
if (
SPEED_TEST_SUITES.hasOwnProperty(message.speed_test_suite) &&
SPEED_TEST_SUITES[message.speed_test_suite] === SPEED_TEST_SUITES.MLAB &&
!(mlabSpeedTest.isAvailable() || ndt7SpeedTest.isAvailable())
) {
return SPEED_TEST_SUITES.OOKLA;
}
if (SPEED_TEST_SUITES.hasOwnProperty(message.speed_test_suite)) {
myConsole.info('%s - speed test suite is forced on message - %s', MODULE_NAME, message.speed_test_suite);
return SPEED_TEST_SUITES[message.speed_test_suite];
}
}
if (
configuration.settings &&
configuration.settings.speed_test_suite &&
SPEED_TEST_SUITES.hasOwnProperty(configuration.settings.speed_test_suite)
) {
if (SPEED_TEST_SUITES[configuration.settings.speed_test_suite] === SPEED_TEST_SUITES.MLAB &&
!(mlabSpeedTest.isAvailable() || ndt7SpeedTest.isAvailable())) {
return SPEED_TEST_SUITES.OOKLA;
}
myConsole.info('%s - speed test suite is - %s', MODULE_NAME, configuration.settings.speed_test_suite);
return SPEED_TEST_SUITES[configuration.settings.speed_test_suite];
}
if (DEFAULT_SPEED_TEST_SUITE === SPEED_TEST_SUITES.MLAB &&
!(mlabSpeedTest.isAvailable() || ndt7SpeedTest.isAvailable())) {
myConsole.info('%s - speed test default suite is - %s but is not available, using OOKLA', MODULE_NAME, DEFAULT_SPEED_TEST_SUITE);
return SPEED_TEST_SUITES.OOKLA;
}
myConsole.info('%s - speed test suite is - %s by default', MODULE_NAME, DEFAULT_SPEED_TEST_SUITE);
return DEFAULT_SPEED_TEST_SUITE;
},
};
};