Use double quotes

Convert existing mix of double quotes and single quotes to only use
double quotes unless the string contains double quotes.
This commit is contained in:
Hornwitser committed 2020-06-17 20:53:18 +02:00
1 parent efd759bec5
commit 34aaeee354
48 files changed
+708 -712

No files matched your search

+7 -7
View File
@@ -12,11 +12,11 @@ async function main() {
const args = yargs
.scriptName("build")
.options({
'clean': { describe: "Remove previous builds", type: 'boolean', default: false },
'build': { describe: "Build mod", type: 'boolean', default: true },
'pack': { describe: "Pack into zip file", type: 'boolean', default: true },
"clean": { describe: "Remove previous builds", type: "boolean", default: false },
"build": { describe: "Build mod", type: "boolean", default: true },
"pack": { describe: "Pack into zip file", type: "boolean", default: true },
"source-dir": { describe: "Path to mod source files", nargs: 1, type: "string", default: libPath },
'output-dir': { describe: "Path to output built mod", nargs: 1, type: 'string', default: "dist" },
"output-dir": { describe: "Path to output built mod", nargs: 1, type: "string", default: "dist" },
"bump-patch": { describe: "Increment patch number of build", type: "boolean", default: false },
"factorio-version": { describe: "Override factorio_version", type: "string" },
})
@@ -66,7 +66,7 @@ async function build(args) {
if (args.pack) {
let zip = new JSZip();
let walker = klaw(args.sourceDir)
.on('data', item => {
.on("data", item => {
if (item.stats.isFile()) {
// On Windows the path created uses backslashes as the directory sepparator
// but the zip file needs to use forward slashes. We can't use the posix
@@ -76,7 +76,7 @@ async function build(args) {
}
})
;
await events.once(walker, 'end');
await events.once(walker, "end");
for (let pathParts of info.additional_files || []) {
let filePath = path.join(...pathParts);
@@ -89,7 +89,7 @@ async function build(args) {
let modPath = path.join(args.outputDir, `${modName}.zip`);
console.log(`Writing ${modPath}`);
let writeStream = zip.generateNodeStream().pipe(fs.createWriteStream(modPath));
await events.once(writeStream, 'finish');
await events.once(writeStream, "finish");
} else {
let modDir = path.join(args.outputDir, modName);
+34 -34
View File
@@ -6,7 +6,7 @@ const jwt = require("jsonwebtoken");
const fs = require("fs-extra");
const yargs = require("yargs");
const version = require("./package").version;
const asTable = require("as-table").configure({delimiter: ' | '});
const asTable = require("as-table").configure({delimiter: " | "});
const chalk = require("chalk");
const events = require("events");
@@ -25,14 +25,14 @@ const config = require("lib/config");
*/
function formatOutputColored(output) {
let time = "";
if (output.format === 'seconds') {
time = chalk.yellow(output.time.padStart(8)) + ' ';
} else if (output.format === 'date') {
time = chalk.yellow(output.time) + ' ';
if (output.format === "seconds") {
time = chalk.yellow(output.time.padStart(8)) + " ";
} else if (output.format === "date") {
time = chalk.yellow(output.time) + " ";
}
let info = "";
if (output.type === 'log') {
if (output.type === "log") {
let level = output.level;
if (level === "Info") {
level = chalk.bold.blueBright(level);
@@ -42,10 +42,10 @@ function formatOutputColored(output) {
level = chalk.bold.redBright(level);
}
info = level + ' ' + chalk.gray(output.file) + ': ';
info = level + " " + chalk.gray(output.file) + ": ";
} else if (output.type === 'action') {
info = '[' + chalk.yellow(output.action) + '] ';
} else if (output.type === "action") {
info = "[" + chalk.yellow(output.action) + "] ";
}
return time + info + output.message;
@@ -237,21 +237,21 @@ commands.push(new Command({
}));
commands.push(new Command({
definition: ['create-instance', "Create an instance", (yargs) => {
definition: ["create-instance", "Create an instance", (yargs) => {
// XXX TODO: set any specific options?
yargs.option('name', {
yargs.option("name", {
type: "string",
nargs: 1,
describe: "Instance name",
group: "Instance Config:",
});
yargs.option('id', {
yargs.option("id", {
type: "number",
nargs: 1,
describe: "Instance ID",
group: "Instance Config:",
});
yargs.option('base', {
yargs.option("base", {
type: "boolean",
nargs: 0,
describe: "Specify this is a base config",
@@ -329,10 +329,10 @@ commands.push(new Command({
}));
commands.push(new Command({
definition: ['assign-instance', "Assign instance to a slave", (yargs) => {
definition: ["assign-instance", "Assign instance to a slave", (yargs) => {
yargs.options({
'instance': { describe: "Instance to assign", nargs: 1, type: 'string', demandOption: true },
'slave': { describe: "Slave to assign to", nargs: 1, type: 'string', demandOption: true },
"instance": { describe: "Instance to assign", nargs: 1, type: "string", demandOption: true },
"slave": { describe: "Slave to assign to", nargs: 1, type: "string", demandOption: true },
});
}],
handler: async function(args, control) {
@@ -346,9 +346,9 @@ commands.push(new Command({
}));
commands.push(new Command({
definition: ['create-save', "Create a new save on an instance", (yargs) => {
definition: ["create-save", "Create a new save on an instance", (yargs) => {
yargs.options({
'instance': { describe: "Instance to create on", nargs: 1, type: 'string', demandOption: true },
"instance": { describe: "Instance to create on", nargs: 1, type: "string", demandOption: true },
});
}],
handler: async function(args, control) {
@@ -361,9 +361,9 @@ commands.push(new Command({
}));
commands.push(new Command({
definition: ['export-data', "Export item icons and locale from instance", (yargs) => {
definition: ["export-data", "Export item icons and locale from instance", (yargs) => {
yargs.options({
'instance': { describe: "Instance to export from", nargs: 1, type: 'string', demandOption: true },
"instance": { describe: "Instance to export from", nargs: 1, type: "string", demandOption: true },
});
}],
handler: async function(args, control) {
@@ -376,10 +376,10 @@ commands.push(new Command({
}));
commands.push(new Command({
definition: ['start-instance', "Start instance", (yargs) => {
definition: ["start-instance", "Start instance", (yargs) => {
yargs.options({
'instance': { describe: "Instance to start", nargs: 1, type: 'string', demandOption: true },
'save': { describe: "Save load, defaults to latest", nargs: 1, type: 'string' },
"instance": { describe: "Instance to start", nargs: 1, type: "string", demandOption: true },
"save": { describe: "Save load, defaults to latest", nargs: 1, type: "string" },
});
}],
handler: async function(args, control) {
@@ -393,9 +393,9 @@ commands.push(new Command({
}));
commands.push(new Command({
definition: ['stop-instance', "Stop instance", (yargs) => {
definition: ["stop-instance", "Stop instance", (yargs) => {
yargs.options({
'instance': { describe: "Instance to stop", nargs: 1, type: 'string', demandOption: true },
"instance": { describe: "Instance to stop", nargs: 1, type: "string", demandOption: true },
});
}],
handler: async function(args, control) {
@@ -408,9 +408,9 @@ commands.push(new Command({
}));
commands.push(new Command({
definition: ['delete-instance', "Delete instance", (yargs) => {
definition: ["delete-instance", "Delete instance", (yargs) => {
yargs.options({
'instance': { describe: "Instance to delete", nargs: 1, type: 'string', demandOption: true },
"instance": { describe: "Instance to delete", nargs: 1, type: "string", demandOption: true },
});
}],
handler: async function(args, control) {
@@ -421,10 +421,10 @@ commands.push(new Command({
}));
commands.push(new Command({
definition: ['send-rcon', "Send RCON command", (yargs) => {
definition: ["send-rcon", "Send RCON command", (yargs) => {
yargs.options({
'instance': { describe: "Instance to sent to", nargs: 1, type: 'string', demandOption: true },
'command': { describe: "command to send", nargs: 1, type: 'string', demandOption: true },
"instance": { describe: "Instance to sent to", nargs: 1, type: "string", demandOption: true },
"command": { describe: "command to send", nargs: 1, type: "string", demandOption: true },
});
}],
handler: async function(args, control) {
@@ -623,7 +623,7 @@ class Control extends link.Link {
// I don't like God classes, but the alternative of putting all this state
// into global variables is not much better.
constructor(connector) {
super('control', 'master', connector);
super("control", "master", connector);
link.attachAllMessages(this);
}
@@ -656,12 +656,12 @@ async function startControl() {
yargs
.scriptName("clusterctl")
.usage("$0 <command> [options]")
.option('config', {
.option("config", {
nargs: 1,
describe: "config file to get credentails from",
default: "config-control.json",
defaultDescription: "auto",
type: 'string',
type: "string",
})
.command("control-config", "Manage Control config", config.configCommand)
.wrap(yargs.terminalWidth())
@@ -684,7 +684,7 @@ async function startControl() {
await controlConfig.load(JSON.parse(await fs.readFile(args.config)));
} catch (err) {
if (err.code === 'ENOENT') {
if (err.code === "ENOENT") {
console.log("Config not found, initializing new config");
await controlConfig.init();
+1 -5
View File
@@ -183,13 +183,9 @@ are at least a few things that have been agreed upon.
JavaScript and Lua code should use double quoted strings (`"string"`)
for all strings with the only exception that strings that contain double
quotes may use single quotes (i.e., `'String with "quotes"'`.) For
quotes may use single quotes (i.e., `'String with "quotes"'`).
JavaScript template literals may also be used where appropriate.
There are places in the codebase that are using `'single'` quoted
strings. Should you be modifying such code use double quotes on new and
modified lines and leave the rest untouched.
### Indenting
+5 -5
View File
@@ -47,7 +47,7 @@ class InvalidField extends Error { };
function splitOn(separator, string) {
let index = string.indexOf(separator);
if (index === -1) {
return [string, ''];
return [string, ""];
}
return [string.slice(0, index), string.slice(index + separator.length)];
}
@@ -152,7 +152,7 @@ class Config extends events.EventEmitter {
* Get the value for a config field
*/
get(name) {
let [group, field] = splitOn('.', name);
let [group, field] = splitOn(".", name);
return this.group(group).get(field);
}
@@ -160,7 +160,7 @@ class Config extends events.EventEmitter {
* Set the value for a config field
*/
set(name, value) {
let [group, field] = splitOn('.', name);
let [group, field] = splitOn(".", name);
return this.group(group).set(field, value);
}
@@ -168,7 +168,7 @@ class Config extends events.EventEmitter {
* Set property of an object value for a config field
*/
setProp(name, prop, value) {
let [group, field] = splitOn('.', name);
let [group, field] = splitOn(".", name);
return this.group(group).setProp(field, prop, value);
}
@@ -350,7 +350,7 @@ class ConfigGroup {
}
if (def.enum && !def.enum.includes(value)) {
throw new InvalidValue(`Expected one of [${def.enum.join(', ')}], not ${value}`);
throw new InvalidValue(`Expected one of [${def.enum.join(", ")}], not ${value}`);
}
if (basicType(value) === "string") {
+3 -3
View File
@@ -21,7 +21,7 @@ const { basicType } = require("lib/helpers");
function mapToObject(map) {
let obj = {};
for (let [key, value] of map) {
if (typeof key !== 'string') {
if (typeof key !== "string") {
throw new Error(
`Expected all keys to be string but got ${typeof key}`
);
@@ -105,11 +105,11 @@ async function loadJsonArrayAsMap(filePath) {
let map = new Map();
for (let element of parsed) {
if (basicType(element) !== "object") {
throw new Error(`Expected all elements to be objects`);
throw new Error("Expected all elements to be objects");
}
if (element.id === undefined) {
throw new Error(`Expected all elements to have an id property`);
throw new Error("Expected all elements to have an id property");
}
map.set(element.id, element);
+2 -2
View File
@@ -5,6 +5,6 @@
*/
module.exports = {
...require("lib/factorio/export"),
...require('lib/factorio/patch'),
...require('lib/factorio/server'),
...require("lib/factorio/patch"),
...require("lib/factorio/server"),
};
+12 -12
View File
@@ -44,12 +44,12 @@ function findRoot(zip) {
if (root === null) {
root = pathRoot;
} else if (root !== pathRoot) {
throw new Error(`Zip contains multiple root folders`);
throw new Error("Zip contains multiple root folders");
}
});
if (root === null) {
throw new Error(`Empty zip file`);
throw new Error("Empty zip file");
}
return root;
@@ -66,13 +66,13 @@ function findRoot(zip) {
*/
function generateLoader(patchInfo) {
let lines = [
'-- Auto generated scenario module loader created by Clusterio',
'-- Modifications to this file will be lost when loaded in Clusterio',
"-- Auto generated scenario module loader created by Clusterio",
"-- Modifications to this file will be lost when loaded in Clusterio",
`clusterio_patch_number = ${patchInfo.patch_number}`,
'',
"",
'local event_handler = require("event_handler")',
'',
'-- Scenario modules',
"",
"-- Scenario modules",
];
for (let moduleName of patchInfo["scenario"]["modules"]) {
@@ -80,8 +80,8 @@ function generateLoader(patchInfo) {
}
lines.push(...[
'',
'-- Clusterio modules',
"",
"-- Clusterio modules",
]);
for (let module of patchInfo["modules"]) {
@@ -97,9 +97,9 @@ function generateLoader(patchInfo) {
}
// End last line with a newline
lines.push('');
lines.push("");
return lines.join('\n');
return lines.join("\n");
}
/**
@@ -253,7 +253,7 @@ async function patch(savePath, modules) {
"files": [],
}
let dirs = [[module.path, '']];
let dirs = [[module.path, ""]];
while (dirs.length) {
let [dir, relativeDir] = dirs.pop();
for (let entry of await fs.readdir(dir, { withFileTypes: true })) {
+72 -72
View File
@@ -157,7 +157,7 @@ function randomDynamicPort() {
*/
async function generatePassword(length) {
function validChar(byte) {
const ranges = ['az', 'AZ', '09'];
const ranges = ["az", "AZ", "09"];
return ranges.some(range =>
range.codePointAt(0) <= byte && byte <= range.codePointAt(1)
);
@@ -355,29 +355,29 @@ function parseOutput(line, source) {
const outputHeuristics = [
// Message indicating the RCON interface has started
{
filter: { type: 'log', message: /^Starting RCON interface/ },
filter: { type: "log", message: /^Starting RCON interface/ },
action: function(output) {
this._startRcon().catch((err) => { this.emit('error', err); });
this._startRcon().catch((err) => { this.emit("error", err); });
},
},
// Message indicating the server is done starting up
{
filter: { type: 'log', message: /^updateTick\(\d+\) changing state from\(CreatingGame\) to\(InGame\)$/ },
filter: { type: "log", message: /^updateTick\(\d+\) changing state from\(CreatingGame\) to\(InGame\)$/ },
action: function(output) {
this._notifyGameReady().catch((err) => { this.emit('error', err); });
this._notifyGameReady().catch((err) => { this.emit("error", err); });
}
},
// Message indicating the server has started an autosave
{
filter: {
type: 'log',
type: "log",
message: /^Saving to _autosave\d+ \((non-)?blocking\)\.$/,
},
action: function(output) {
let name = /^Saving to (_autosave\d+) /.exec(output.message)[1];
this.emit('_autosave', name);
this.emit("_autosave", name);
},
},
@@ -395,7 +395,7 @@ const outputHeuristics = [
// Message indicating the server has finished saving
{
filter: {
type: 'log',
type: "log",
message: [
"Saving finished",
@@ -404,18 +404,18 @@ const outputHeuristics = [
],
},
action: function(output) {
this.emit('_saved');
this.emit("_saved");
}
},
// Message indicating the server is shutting down
{
filter: {
type: 'generic',
type: "generic",
message: /^Quitting: /
},
action: function(output) {
this.emit('_quitting');
this.emit("_quitting");
// On windows the Factorio server will wait for input on the console input buffer
// when an error occurs. Since we can't send input there we terminate the server
@@ -429,8 +429,8 @@ const outputHeuristics = [
// Messages that might be tha cause of an unexpected shutdown.
{
filter: {
type: 'log',
level: 'Error',
type: "log",
level: "Error",
message: [
"MultiplayerManager failed: \"Binding IPv4 socket failed: Permission denied\"",
"MultiplayerManager failed: Host address is already in use.",
@@ -442,8 +442,8 @@ const outputHeuristics = [
},
{
filter: {
type: 'log',
level: 'Error',
type: "log",
level: "Error",
message: [
"Can't bind socket: Address already in use",
"Can't bind socket: Permission denied",
@@ -515,8 +515,8 @@ class FactorioServer extends events.EventEmitter {
// Array of possible causes for an unexpected shutdown
this._unexpected = [];
this._stdout = new LineSplitter((line) => { this._handleOutput(line, 'stdout'); });
this._stderr = new LineSplitter((line) => { this._handleOutput(line, 'stderr'); });
this._stdout = new LineSplitter((line) => { this._handleOutput(line, "stdout"); });
this._stderr = new LineSplitter((line) => { this._handleOutput(line, "stderr"); });
// Track autosaving
this._runningAutosave = null;
@@ -542,39 +542,39 @@ class FactorioServer extends events.EventEmitter {
}
async _handleIpc(line) {
let channelEnd = line.indexOf('?');
let channelEnd = line.indexOf("?");
if (channelEnd === -1) {
throw new Error(`Malformed IPC line "${line.toString()}"`);
}
let channel = line
.slice(6, channelEnd)
.toString('utf-8')
.toString("utf-8")
.replace(/\\x([0-9a-f]{2})/g, (match, p1) =>
String.fromCharCode(parseInt(p1, 16))
)
;
let type = line.slice(channelEnd + 1, channelEnd + 2).toString('utf-8');
let type = line.slice(channelEnd + 1, channelEnd + 2).toString("utf-8");
let content;
if (type === 'j') {
content = JSON.parse(line.slice(channelEnd + 2).toString('utf-8'));
if (type === "j") {
content = JSON.parse(line.slice(channelEnd + 2).toString("utf-8"));
} else if (type === 'f') {
let fileName = line.slice(channelEnd + 2).toString('utf-8');
let filePath = this.writePath('script-output', fileName);
} else if (type === "f") {
let fileName = line.slice(channelEnd + 2).toString("utf-8");
let filePath = this.writePath("script-output", fileName);
// Prevent malicious names
if (/[\\/\0]/.test(fileName)) {
throw new Error(`Invalid IPC file name '${fileName}'`)
}
if (fileName.endsWith('.json')) {
content = JSON.parse(await fs.readFile(filePath, 'utf-8'));
if (fileName.endsWith(".json")) {
content = JSON.parse(await fs.readFile(filePath, "utf-8"));
await fs.unlink(filePath);
} else {
let format = fileName.slice(fileName.lastIndexOf('.') + 1);
let format = fileName.slice(fileName.lastIndexOf(".") + 1);
throw new Error(`Unknown IPC file format '${format}'`)
}
@@ -589,13 +589,13 @@ class FactorioServer extends events.EventEmitter {
_handleOutput(line, source) {
if (line.slice(0, 6).equals(Buffer.from("\f$ipc:"))) {
this._handleIpc(line).catch(err => this.emit('error', err));
this._handleIpc(line).catch(err => this.emit("error", err));
return;
}
this.emit(source, line);
let output = parseOutput(line.toString('utf-8'), source);
let output = parseOutput(line.toString("utf-8"), source);
heuristicLoop: for (let heuristic of outputHeuristics) {
for (let [name, expected] of Object.entries(heuristic.filter)) {
if (!Object.hasOwnProperty.call(output, name)) {
@@ -621,7 +621,7 @@ class FactorioServer extends events.EventEmitter {
heuristic.action.call(this, output);
}
this.emit('output', output);
this.emit("output", output);
}
async _startRcon() {
@@ -643,7 +643,7 @@ class FactorioServer extends events.EventEmitter {
this._rconClient = new rconClient.Rcon(config);
this._rconClient.on("error", err => { /* Ignore */ });
this._rconClient.on('authenticated', () => { this._rconReady = true; this.emit('rcon-ready'); });
this._rconClient.on("authenticated", () => { this._rconReady = true; this.emit("rcon-ready"); });
this._rconClient.on("end", () => {
this._rconClient = null;
this._rconReady = false;
@@ -685,18 +685,18 @@ class FactorioServer extends events.EventEmitter {
}
_attachStdio() {
this._server.stdout.on('data', chunk => { this._stdout.data(chunk); });
this._server.stdout.on('close', () => { this._stdout.end(); });
this._server.stderr.on('data', chunk => { this._stderr.data(chunk); });
this._server.stderr.on('close', () => { this._stderr.end(); });
this._server.stdout.on("data", chunk => { this._stdout.data(chunk); });
this._server.stdout.on("close", () => { this._stdout.end(); });
this._server.stderr.on("data", chunk => { this._stderr.data(chunk); });
this._server.stderr.on("close", () => { this._stderr.end(); });
}
_watchExit() {
this._server.on('exit', (code, signal) => {
this._server.on("exit", (code, signal) => {
if (this._state !== "stopping") {
if (this._unexpected.length === 0) {
if (signal === 'SIGKILL') {
this.emit('error', new errors.EnvironmentError(
if (signal === "SIGKILL") {
this.emit("error", new errors.EnvironmentError(
"Factorio server was unexpectedly killed, is the system low on memory?"
));
@@ -708,14 +708,14 @@ class FactorioServer extends events.EventEmitter {
msg = `Factorio server was unexpectedly shut by down by signal ${signal}`;
}
this.emit('error', new Error(msg));
this.emit("error", new Error(msg));
}
} else if (this._unexpected.length === 1) {
this.emit('error', new Error(this._unexpected[0]));
this.emit("error", new Error(this._unexpected[0]));
} else {
this.emit('error', new Error(
this.emit("error", new Error(
"Factorio server unexpectedly shut down. Possible causes:\n- "+
this._unexpected.join("\n- ")
));
@@ -737,12 +737,12 @@ class FactorioServer extends events.EventEmitter {
async _notifyGameReady() {
this._gameReady = true;
this.emit('game-ready');
this.emit("game-ready");
}
async _waitForReady() {
if (!this._gameReady) {
await events.once(this, 'game-ready');
await events.once(this, "game-ready");
}
}
@@ -761,14 +761,14 @@ class FactorioServer extends events.EventEmitter {
await this._writeConfigIni();
this._server = child_process.spawn(
this.dataPath('..', 'bin', 'x64', 'factorio'),
this.dataPath("..", "bin", "x64", "factorio"),
[
'--config', this.writePath('config.ini'),
'--create', this.writePath('saves', name),
"--config", this.writePath("config.ini"),
"--create", this.writePath("saves", name),
],
{
detached: true,
stdio: 'pipe',
stdio: "pipe",
}
);
@@ -776,7 +776,7 @@ class FactorioServer extends events.EventEmitter {
this._server.once("exit", () => this.emit("exit"));
try {
let [code, signal] = await events.once(this._server, 'exit');
let [code, signal] = await events.once(this._server, "exit");
if (code !== 0) {
throw new Error(`Factorio exited with status ${code}`);
}
@@ -799,17 +799,17 @@ class FactorioServer extends events.EventEmitter {
await this._writeConfigIni();
this._server = child_process.spawn(
this.dataPath('..', 'bin', 'x64', 'factorio'),
this.dataPath("..", "bin", "x64", "factorio"),
[
'--config', this.writePath('config.ini'),
'--start-server', this.writePath('saves', save),
'--port', this.gamePort,
'--rcon-port', this.rconPort,
'--rcon-password', this.rconPassword,
"--config", this.writePath("config.ini"),
"--start-server", this.writePath("saves", save),
"--port", this.gamePort,
"--rcon-port", this.rconPort,
"--rcon-password", this.rconPassword,
],
{
detached: true,
stdio: 'pipe',
stdio: "pipe",
}
);
@@ -832,17 +832,17 @@ class FactorioServer extends events.EventEmitter {
await this._writeConfigIni();
this._server = child_process.spawn(
this.dataPath('..', 'bin', 'x64', 'factorio'),
this.dataPath("..", "bin", "x64", "factorio"),
[
'--config', this.writePath('config.ini'),
'--start-server-load-scenario', scenario,
'--port', this.gamePort,
'--rcon-port', this.rconPort,
'--rcon-password', this.rconPassword,
"--config", this.writePath("config.ini"),
"--start-server-load-scenario", scenario,
"--port", this.gamePort,
"--rcon-port", this.rconPort,
"--rcon-password", this.rconPassword,
],
{
detached: true,
stdio: 'pipe',
stdio: "pipe",
}
);
@@ -867,11 +867,11 @@ class FactorioServer extends events.EventEmitter {
async sendRcon(message, expectEmpty) {
this._check(["running", "stopping"])
if (!this._rconReady) {
await events.once(this, 'rcon-ready');
await events.once(this, "rcon-ready");
}
let response = await this._rconClient.send(message);
if (expectEmpty && response !== '') {
if (expectEmpty && response !== "") {
throw new Error(`Expected empty response but got "${response}"`);
}
return response;
@@ -923,7 +923,7 @@ class FactorioServer extends events.EventEmitter {
// If RCON is not yet fully connected that operation needs to
// complete before the RCON connection can be closed cleanly.
if (!this._rconReady) {
await events.once(this, 'rcon-ready');
await events.once(this, "rcon-ready");
}
await this._rconClient.end();
@@ -942,16 +942,16 @@ class FactorioServer extends events.EventEmitter {
// stop if it's stuck with an infinite lua code loop. In either
// case there's no recovering from it.
if (process.platform !== "win32") {
this.on('_quitting', setAlive);
await events.once(this._server, 'exit');
this.on("_quitting", setAlive);
await events.once(this._server, "exit");
clearTimeout(timeoutId);
this.off('_quitting', setAlive);
this.off("_quitting", setAlive);
// On windows the process is terminated immediately, but to keep
// ordering wait until after the exit event here.
} else {
await events.once(this._server, 'exit');
await events.once(this._server, "exit");
}
}
@@ -981,14 +981,14 @@ class FactorioServer extends events.EventEmitter {
this._check(["running"]);
let check = await this.sendRcon("/sc rcon.print('disabled')");
if (check === 'disabled\n') {
if (check === "disabled\n") {
return false;
}
// Factorio will print a warning to the console and ask for the command
// to be runned again before disabling achievements and allowing commands.
check = await this.sendRcon("/sc rcon.print('disabled')");
if (check === 'disabled\n') {
if (check === "disabled\n") {
return true;
}
+6 -6
View File
@@ -2,8 +2,8 @@
* Hashing functions
* @module
*/
const crypto = require('crypto');
const fs = require('fs');
const crypto = require("crypto");
const fs = require("fs");
/**
@@ -14,13 +14,13 @@ const fs = require('fs');
*/
function hashStream(stream) {
return new Promise(function(resolve, reject) {
let hasher = crypto.createHash('sha1')
hasher.setEncoding('hex')
hasher.on('finish', function() {
let hasher = crypto.createHash("sha1")
hasher.setEncoding("hex")
hasher.on("finish", function() {
resolve(hasher.read());
});
stream.on('error', function(error) {
stream.on("error", function(error) {
// the docs doesn't say anything about what's passed on error
reject(error);
});
+3 -3
View File
@@ -356,7 +356,7 @@ class WebSocketClientConnector extends WebSocketBaseConnector {
}
let { seq, type, data } = message;
if (type == 'hello') {
if (type == "hello") {
console.log(`SOCKET | received hello from master version ${data.version}`);
this.emit("hello", data);
if (this._sessionToken) {
@@ -369,7 +369,7 @@ class WebSocketClientConnector extends WebSocketBaseConnector {
this.register();
}
} else if (type === 'ready') {
} else if (type === "ready") {
console.log("SOCKET | received ready from master");
this._state = "connected";
this._sessionToken = data.session_token;
@@ -452,7 +452,7 @@ class VirtualConnector extends events.EventEmitter {
* @returns the sequence number of the message sent
*/
send(type, data) {
this.other.emit('message', { seq: this._seq, type, data });
this.other.emit("message", { seq: this._seq, type, data });
return this._seq++;
}
}
+3 -3
View File
@@ -4,7 +4,7 @@
* @author Hornwitser
*/
module.exports = {
...require('lib/link/link'),
...require('lib/link/messages'),
...require('lib/link/connectors'),
...require("lib/link/link"),
...require("lib/link/messages"),
...require("lib/link/connectors"),
};
+2 -2
View File
@@ -30,7 +30,7 @@ class Link {
this._validators = new Map();
// Process messages received by the connector
connector.on('message', payload => {
connector.on("message", payload => {
try {
this.processMessage(payload);
} catch (err) {
@@ -40,7 +40,7 @@ class Link {
console.error(err.errors);
}
} else {
this.connector.emit('error', err);
this.connector.emit("error", err);
}
}
});
+49 -49
View File
@@ -67,8 +67,8 @@ class Request extends Message {
this.permission = permission || null;
this.forwardTo = forwardTo;
this.requestType = type + '_request';
this.responseType = type + '_response';
this.requestType = type + "_request";
this.responseType = type + "_response";
if (permission === undefined && links.includes("control-master")) {
throw new Error(`permission is required for ${this.type} request over control-master links`);
@@ -77,7 +77,7 @@ class Request extends Message {
throw new Error(`permission is not allowed on ${this.type} request as it is not over control-master link`);
}
if (forwardTo === 'instance') {
if (forwardTo === "instance") {
requestProperties = Object.assign(
{"instance_id": { type: "integer" }}, requestProperties
);
@@ -158,7 +158,7 @@ class Request extends Message {
// Use forwarder if handler is not present.
if (!handler) {
if (this.forwardTo === 'instance') {
if (this.forwardTo === "instance") {
handler = link.forwardRequestToInstance;
} else if (this.forwardTo === "master") {
handler = link.forwardRequestToMaster;
@@ -256,8 +256,8 @@ messages.debugDumpWs = new Request({
// Management requests
messages.listSlaves = new Request({
type: 'list_slaves',
links: ['control-master'],
type: "list_slaves",
links: ["control-master"],
permission: "core.slave.list",
responseProperties: {
"list": {
@@ -278,8 +278,8 @@ messages.listSlaves = new Request({
});
messages.listInstances = new Request({
type: 'list_instances',
links: ['control-master'],
type: "list_instances",
links: ["control-master"],
permission: "core.instance.list",
responseProperties: {
"list": {
@@ -324,8 +324,8 @@ messages.createSlaveConfig = new Request({
});
messages.setInstanceOutputSubscriptions = new Request({
type: 'set_instance_output_subscriptions',
links: ['control-master'],
type: "set_instance_output_subscriptions",
links: ["control-master"],
permission: "core.instance.follow_log",
requestProperties: {
"instance_ids": {
@@ -336,8 +336,8 @@ messages.setInstanceOutputSubscriptions = new Request({
});
messages.createInstance = new Request({
type: 'create_instance',
links: ['control-master'],
type: "create_instance",
links: ["control-master"],
permission: "core.instance.create",
requestProperties: {
"serialized_config": { type: "object" },
@@ -380,8 +380,8 @@ messages.setInstanceConfigProp = new Request({
});
messages.assignInstanceCommand = new Request({
type: 'assign_instance_command',
links: ['control-master'],
type: "assign_instance_command",
links: ["control-master"],
permission: "core.instance.assign",
requestProperties: {
"instance_id": { type: "integer" },
@@ -390,29 +390,29 @@ messages.assignInstanceCommand = new Request({
});
messages.assignInstance = new Request({
type: 'assign_instance',
links: ['master-slave'],
type: "assign_instance",
links: ["master-slave"],
requestProperties: {
"serialized_config": { type: "object" },
},
forwardTo: 'instance',
forwardTo: "instance",
})
messages.startInstance = new Request({
type: 'start_instance',
links: ['control-master', 'master-slave', 'slave-instance'],
type: "start_instance",
links: ["control-master", "master-slave", "slave-instance"],
permission: "core.instance.start",
requestProperties: {
"save": { type: ["string", "null"] },
},
forwardTo: 'instance',
forwardTo: "instance",
});
messages.createSave = new Request({
type: 'create_save',
links: ['control-master', 'master-slave', 'slave-instance'],
type: "create_save",
links: ["control-master", "master-slave", "slave-instance"],
permission: "core.instance.create_save",
forwardTo: 'instance',
forwardTo: "instance",
});
messages.exportData = new Request({
@@ -423,24 +423,24 @@ messages.exportData = new Request({
});
messages.stopInstance = new Request({
type: 'stop_instance',
links: ['control-master', 'master-slave', 'slave-instance'],
type: "stop_instance",
links: ["control-master", "master-slave", "slave-instance"],
permission: "core.instance.stop",
forwardTo: 'instance',
forwardTo: "instance",
});
messages.deleteInstance = new Request({
type: 'delete_instance',
links: ['control-master', 'master-slave'],
type: "delete_instance",
links: ["control-master", "master-slave"],
permission: "core.instance.delete",
forwardTo: 'instance',
forwardTo: "instance",
});
messages.sendRcon = new Request({
type: 'send_rcon',
links: ['control-master', 'master-slave', 'slave-instance'],
type: "send_rcon",
links: ["control-master", "master-slave", "slave-instance"],
permission: "core.instance.send_rcon",
forwardTo: 'instance',
forwardTo: "instance",
requestProperties: {
"command": { type: "string" },
},
@@ -583,8 +583,8 @@ messages.deleteUser = new Request({
});
messages.getMetrics = new Request({
type: 'statistics_exporter:get_metrics',
links: ['master-slave', 'slave-instance'],
type: "statistics_exporter:get_metrics",
links: ["master-slave", "slave-instance"],
responseProperties: {
"results": { type: "array" },
},
@@ -632,20 +632,20 @@ class Event extends Message {
this.forwardTo = forwardTo;
this.broadcastTo = broadcastTo;
if (forwardTo === 'instance') {
if (forwardTo === "instance") {
eventProperties = Object.assign(
{"instance_id": { type: "integer" }}, eventProperties
);
} else if (forwardTo !== 'master' && forwardTo !== null) {
} else if (forwardTo !== "master" && forwardTo !== null) {
throw new Error(`Invalid forwardTo value ${forwardTo}`);
}
if (broadcastTo !== 'instance' && broadcastTo !== null) {
if (broadcastTo !== "instance" && broadcastTo !== null) {
throw new Error(`Invalid broadcastTo value ${broadcastTo}`);
}
this.eventType = type + '_event';
this.eventType = type + "_event";
this._eventValidator = schema.compile({
$schema: "http://json-schema.org/draft-07/schema#",
properties: {
@@ -685,17 +685,17 @@ class Event extends Message {
if (this.links.includes(`${link.target}-${link.source}`)) {
// Use forwarder if handler is not present.
if (!handler) {
if (this.forwardTo === 'instance') {
if (this.forwardTo === "instance") {
handler = link.forwardEventToInstance;
} else if (this.forwardTo === 'master') {
} else if (this.forwardTo === "master") {
handler = link.forwardEventToMaster;
}
}
if (
this.broadcastTo === 'instance'
this.broadcastTo === "instance"
&& [
'instance-slave', 'slave-master', 'control-master', 'master-slave'
"instance-slave", "slave-master", "control-master", "master-slave"
].includes(`${link.target}-${link.source}`)
) {
if (!handler) {
@@ -765,7 +765,7 @@ messages.instanceStarted = new Event({
},
});
messages.instanceStopped = new Event({
type: 'instance_stopped',
type: "instance_stopped",
links: ["instance-slave", "slave-master"],
eventProperties: {
"instance_id": { type: "integer" },
@@ -773,8 +773,8 @@ messages.instanceStopped = new Event({
});
messages.updateInstances = new Event({
type: 'update_instances',
links: ['slave-master'],
type: "update_instances",
links: ["slave-master"],
eventProperties: {
"instances": {
type: "array",
@@ -792,9 +792,9 @@ messages.updateInstances = new Event({
});
messages.instanceOutput = new Event({
type: 'instance_output',
links: ['instance-slave', 'slave-master', 'master-control'],
forwardTo: 'master',
type: "instance_output",
links: ["instance-slave", "slave-master", "master-control"],
forwardTo: "master",
eventProperties: {
"instance_id": { type: "integer" },
"output": {
@@ -847,7 +847,7 @@ messages.playerEvent = new Event({
*/
function attachAllMessages(link) {
for (let [name, message] of Object.entries(messages)) {
message.attach(link, link[name + message.constructor.name + 'Handler']);
message.attach(link, link[name + message.constructor.name + "Handler"]);
}
}
+12 -12
View File
@@ -3,34 +3,34 @@ Provides tools to manage mods in a clusterio install
@module
*/
const asTable = require("as-table").configure({delimiter: ' | '});
const asTable = require("as-table").configure({delimiter: " | "});
const moment = require("moment");
const syncRequest = require("sync-request");
const fs = require("fs-extra");
const https = require('follow-redirects').https;
const https = require("follow-redirects").https;
const factorioAPI = require("node-factorio-api");
const sLog = require("single-line-log").stdout;
const query = require('cli-interact').getYesNo;
const query = require("cli-interact").getYesNo;
const path = require("path");
const fileOps = require("lib/fileOps");
function ellipse(str, max){
return str.length > (max - 3) ? str.substring(0,max-3) + '...' : str;
return str.length > (max - 3) ? str.substring(0,max-3) + "..." : str;
}
// https://stackoverflow.com/questions/15900485/correct-way-to-convert-size-in-bytes-to-kb-mb-gb-in-javascript
function formatBytes(size, decimals) {
if (bytes === 0) return '0 Bytes';
if (bytes === 0) return "0 Bytes";
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
}
@@ -78,7 +78,7 @@ async function listMods(config, instance) {
});
} else {
// list shared mods in /sharedMods/
factorioAPI.init(false, 'sharedMods/', '', instance.server.version);
factorioAPI.init(false, "sharedMods/", "", instance.server.version);
factorioAPI.authenticate({
username: config.username,
token: config.token,
@@ -168,7 +168,7 @@ async function addMod(config, term, instance) {
// treat it as a github releases download
let apiURL = "https://api.github.com/repos/" + term.split("/")[3] + "/" + term.split("/")[4] + "/releases"; // https://api.github.com/repos/Danielv123/factorioClusterioMod/releases
let res = syncRequest('GET', apiURL, {"headers":{"User-Agent":"factorioClusterio"}});
let res = syncRequest("GET", apiURL, {"headers":{"User-Agent":"factorioClusterio"}});
let url = JSON.parse(res.getBody())[0].assets[0].browser_download_url;
let name = JSON.parse(res.getBody())[0].assets[0].name;
if (url) {
@@ -177,7 +177,7 @@ async function addMod(config, term, instance) {
let bytesDownloaded = 0;
let downloadStartTime = Date.now();
https.get(url, function(response) {
let bytesToDownload = response.headers['content-length'];
let bytesToDownload = response.headers["content-length"];
response.pipe(file);
response.on("data", chunk => {
bytesDownloaded += chunk.length;
@@ -188,7 +188,7 @@ async function addMod(config, term, instance) {
"about "+timeToComplete+" seconds remaining ("+formatBytes(bytesPerSecond)+"/s)");
}).on("end", x => {
sLog.clear();
console.log(" Downloaded in "+moment.utc(moment.duration(Date.now()-downloadStartTime).as('milliseconds')).format('mm:ss')); // because sLog.clear() doesn't seem to do the job of ending the line properly
console.log(" Downloaded in "+moment.utc(moment.duration(Date.now()-downloadStartTime).as("milliseconds")).format("mm:ss")); // because sLog.clear() doesn't seem to do the job of ending the line properly
resolve();
});
});
@@ -261,7 +261,7 @@ the latest release, saving it to /sharedMods
function downloadFromGitURL(url) {
console.log("Downloading mod from "+url);
// get JSON data about releases
let res = syncRequest('GET', url, {"headers":{"User-Agent":"factorioClusterio"}});
let res = syncRequest("GET", url, {"headers":{"User-Agent":"factorioClusterio"}});
let downloadUrl = JSON.parse(res.getBody())[0].assets[0].browser_download_url;
let name = JSON.parse(res.getBody())[0].assets[0].name;
console.log(JSON.parse(res.getBody()))
+3 -3
View File
@@ -1,6 +1,6 @@
var http = require('http');
var https = require('https');
var fs = require('fs-extra');
var http = require("http");
var https = require("https");
var fs = require("fs-extra");
function makeDirectory(path){
+3 -3
View File
@@ -321,10 +321,10 @@ async function loadPluginInfos(baseDir) {
try {
// Note: Require path is relative to this module
pluginInfo = require(path.posix.join('..', baseDir, pluginDir, 'info'));
pluginInfo = require(path.posix.join("..", baseDir, pluginDir, "info"));
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
if (err.code === "MODULE_NOT_FOUND") {
continue;
} else {
throw new errors.PluginError(pluginDir, err);
@@ -359,7 +359,7 @@ function attachPluginMessages(link, pluginInfo, plugin) {
throw new Error(`Type of ${name} message must start with "${pluginInfo.name}:"`);
}
let handler = name + messageFormat.constructor.name + 'Handler';
let handler = name + messageFormat.constructor.name + "Handler";
if (plugin === null || !plugin[handler]) {
messageFormat.attach(link);
+24 -24
View File
@@ -1,10 +1,10 @@
class Metric {
constructor(type, name, help, labels = []) {
if (typeof name !== 'string') {
if (typeof name !== "string") {
throw new Error("Expected name to be a string");
}
if (typeof help !== 'string') {
if (typeof help !== "string") {
throw new Error("Expected help to be a string");
}
@@ -73,7 +73,7 @@ function labelsToKey(labels, metricLabels) {
}
if (labels.length > metricLabels.length) {
throw new Error(`Extra positional label`);
throw new Error("Extra positional label");
}
for (let i=0; i < metricLabels.length; ++i) {
@@ -86,14 +86,14 @@ function labelsToKey(labels, metricLabels) {
}
}
return items.join(',');
return items.join(",");
}
function keyToLabels(key) {
let labels = new Map();
if (key !== '') for (let pair of key.split(',')) {
let [name, value] = pair.split('=', 2);
if (key !== "") for (let pair of key.split(",")) {
let [name, value] = pair.split("=", 2);
labels.set(name, value
.slice(1, -1)
.replace(/\\"/g, "\"")
@@ -111,9 +111,9 @@ class ValueCollector extends Collector {
let register = true;
let callback = null;
for (let [name, value] of Object.entries(options)) {
if (name === 'labels') { labels = value; }
else if (name === 'register') { register = value; }
else if (name === 'callback') { callback = value; }
if (name === "labels") { labels = value; }
else if (name === "register") { register = value; }
else if (name === "callback") { callback = value; }
else { throw new Error(`Unrecognized option '${name}'`); }
}
@@ -151,7 +151,7 @@ class ValueCollector extends Collector {
remove(...labels) {
let key = labelsToKey(labels, this.metric.labels);
if (key === '') {
if (key === "") {
throw new Error("labels cannot be empty");
}
this._children.delete(key);
@@ -309,9 +309,9 @@ function escapeHelp(help) {
function formatValue(value) {
if (value === Infinity) {
return '+Inf';
return "+Inf";
} else if (value === -Infinity) {
return '-Inf';
return "-Inf";
} else {
return value.toString();
}
@@ -323,14 +323,14 @@ async function* expositionLines(resultsIterator) {
if (first) {
first = false;
} else {
yield `\n`
yield "\n"
}
yield `# HELP ${result.metric.name} ${escapeHelp(result.metric.help)}\n`;
yield `# TYPE ${result.metric.name} ${result.metric.type}\n`;
for (let [key, value] of result.samples) {
if (key === '') {
if (key === "") {
yield `${result.metric.name} ${formatValue(value)}\n`;
} else {
yield `${result.metric.name}{${key}} ${formatValue(value)}\n`;
@@ -340,7 +340,7 @@ async function* expositionLines(resultsIterator) {
}
async function exposition(resultsIterator = defaultRegistry.collect()) {
let exposition = '';
let exposition = "";
for await (let line of expositionLines(resultsIterator)) {
exposition += line;
}
@@ -348,16 +348,16 @@ async function exposition(resultsIterator = defaultRegistry.collect()) {
}
// HTTP Content-Type for the exposition format that's implemented
exposition.contentType = 'text/plain; version=0.0.4';
exposition.contentType = "text/plain; version=0.0.4";
function serializeResult(result, options = {}) {
let addLabels = null;
let metricName = result.metric.name;
let metricHelp = result.metric.help;
for (let [name, value] of Object.entries(options)) {
if (name === 'addLabels') { addLabels = value; }
else if (name === 'metricName') { metricName = value; }
else if (name === 'metricHelp') { metricHelp = value; }
if (name === "addLabels") { addLabels = value; }
else if (name === "metricName") { metricName = value; }
else if (name === "metricHelp") { metricHelp = value; }
else { throw new Error(`Unrecognized option '${name}'`); }
}
@@ -370,7 +370,7 @@ function serializeResult(result, options = {}) {
samples = new Map();
let key = labelsToKey([addLabels], [...Object.keys(addLabels)]);
for (let [labels, value] of result.samples.entries()) {
if (labels === '') { samples.set(key, value); }
if (labels === "") { samples.set(key, value); }
else { samples.set(`${labels},${key}`, value); }
}
}
@@ -400,7 +400,7 @@ function deserializeResult(serializedResult) {
let defaultCollectors = {};
defaultCollectors.processCpuSecondsTotal = new Gauge(
'process_cpu_seconds_total',
"process_cpu_seconds_total",
"Total user and system CPU time spent in seconds.",
{
callback: async function() {
@@ -411,7 +411,7 @@ defaultCollectors.processCpuSecondsTotal = new Gauge(
);
defaultCollectors.processResidentMemoryBytes = new Gauge(
'process_resident_memory_bytes',
"process_resident_memory_bytes",
"Resident memory size in bytes.",
{
callback: function() {
@@ -421,7 +421,7 @@ defaultCollectors.processResidentMemoryBytes = new Gauge(
);
defaultCollectors.processHeapBytes = new Gauge(
'process_heap_bytes',
"process_heap_bytes",
"Process heap size in bytes.",
{
callback: function() {
@@ -431,7 +431,7 @@ defaultCollectors.processHeapBytes = new Gauge(
);
defaultCollectors.processStartTimeSeconds = new Gauge(
'process_start_time_seconds',
"process_start_time_seconds",
"Start time of the process since unix epoch in seconds."
);
defaultCollectors.processStartTimeSeconds.setToCurrentTime();
+1 -1
View File
@@ -2,7 +2,7 @@
* JSON schemas used for validating link messages
* @module
*/
const ajv = new (require('ajv'))({
const ajv = new (require("ajv"))({
verbose: true,
format: "full",
extendRefs: "fail",
+40 -40
View File
@@ -19,8 +19,8 @@
const deepmerge = require("deepmerge");
const path = require("path");
const fs = require("fs-extra");
const jwt = require('jsonwebtoken');
const crypto = require('crypto');
const jwt = require("jsonwebtoken");
const crypto = require("crypto");
const moment = require("moment");
const request = require("request");
const setBlocking = require("set-blocking");
@@ -49,30 +49,30 @@ const config = require("lib/config");
const users = require("lib/users");
const express = require("express");
const compression = require('compression');
const cookieParser = require('cookie-parser');
const compression = require("compression");
const cookieParser = require("cookie-parser");
// Required for express post requests
const bodyParser = require("body-parser");
const fileUpload = require('express-fileupload');
const fileUpload = require("express-fileupload");
var app = express();
var httpServer;
var httpsServer;
app.use(cookieParser());
app.use(bodyParser.json({
limit: '10mb',
limit: "10mb",
}));
app.use(bodyParser.urlencoded({
parameterLimit: 100000,
limit: '10mb',
limit: "10mb",
extended: true
}));
app.use(fileUpload());
app.use(compression());
// dynamic HTML generations with EJS
app.set('view engine', 'ejs');
app.set('views', ['views', 'plugins']);
app.set("view engine", "ejs");
app.set("views", ["views", "plugins"]);
// give ejs access to some interesting information
app.use(function(req, res, next){
@@ -88,12 +88,12 @@ app.use(function(req, res, next){
require("./routes")(app);
// Set folder to serve static content from (the website)
app.use(express.static('static'));
app.use(express.static("static"));
const endpointHitCounter = new prometheus.Counter(
"clusterio_master_http_endpoint_hits_total",
"How many requests a particular HTTP endpoint has gotten",
{ labels: ['route'] }
{ labels: ["route"] }
);
const wsMessageCounter = new prometheus.Counter(
@@ -167,10 +167,10 @@ async function getMetrics(req, res, next) {
let text = await prometheus.exposition(results);
res.set('Content-Type', prometheus.exposition.contentType);
res.set("Content-Type", prometheus.exposition.contentType);
res.send(text);
}
app.get('/metrics', (req, res, next) => getMetrics(req, res, next).catch(next));
app.get("/metrics", (req, res, next) => getMetrics(req, res, next).catch(next));
function validateSlaveToken(req, res, next) {
@@ -232,9 +232,9 @@ app.put("/api/upload-export",
);
const masterConnectedClientsCount = new prometheus.Gauge(
'clusterio_master_connected_clients_count', "How many clients are currently connected to this master server",
"clusterio_master_connected_clients_count", "How many clients are currently connected to this master server",
{
labels: ['type'], callback: async function(gauge) {
labels: ["type"], callback: async function(gauge) {
gauge.labels("slave").set(slaveConnections.size);
gauge.labels("control").set(controlConnections.length);
},
@@ -267,7 +267,7 @@ async function loadInstances(databaseDirectory, file) {
}
} catch (err) {
if (err.code !== 'ENOENT') {
if (err.code !== "ENOENT") {
throw err;
}
}
@@ -365,14 +365,14 @@ async function saveUsers(databaseDirectory, file) {
* Innitiate shutdown of master server
*/
async function shutdown() {
console.log('Shutting down');
console.log("Shutting down");
let exitStartTime = Date.now();
try {
console.log("Saving configs");
await fs.outputFile(masterConfigPath, JSON.stringify(masterConfig.serialize(), null, 4));
await saveMap(masterConfig.get('master.database_directory'), "slaves.json", db.slaves);
await saveInstances(masterConfig.get('master.database_directory'), "instances.json", db.instances);
await saveMap(masterConfig.get("master.database_directory"), "slaves.json", db.slaves);
await saveInstances(masterConfig.get("master.database_directory"), "instances.json", db.instances);
await saveUsers(masterConfig.get("master.database_directory"), "users.json");
await plugin.invokeHook(masterPlugins, "onShutdown");
@@ -439,7 +439,7 @@ async function downloadPage(url) {
app.get("/api/modmeta", async function(req, res) {
endpointHitCounter.labels(req.route.path).inc();
res.header("Access-Control-Allow-Origin", "*");
res.setHeader('Content-Type', 'application/json');
res.setHeader("Content-Type", "application/json");
let modData = await downloadPage("https://mods.factorio.com/api/mods/" + req.query.modname);
res.send(modData);
});
@@ -452,7 +452,7 @@ app.get("/api/modmeta", async function(req, res) {
*/
class BaseConnection extends link.Link {
constructor(target, connector) {
super('master', target, connector);
super("master", target, connector);
link.attachAllMessages(this);
for (let masterPlugin of masterPlugins.values()) {
plugin.attachPluginMessages(this, masterPlugin.info, masterPlugin);
@@ -465,7 +465,7 @@ class BaseConnection extends link.Link {
throw new errors.RequestError(`Instance with ID ${message.data.instance_id} does not exist`);
}
let slaveId = instance.config.get('instance.assigned_slave');
let slaveId = instance.config.get("instance.assigned_slave");
if (slaveId === null) {
throw new errors.RequestError("Instance is not assigned to a slave");
}
@@ -485,7 +485,7 @@ class BaseConnection extends link.Link {
let instance = db.instances.get(message.data.instance_id);
if (!instance) { return; }
let slaveId = instance.config.get('instance.assigned_slave');
let slaveId = instance.config.get("instance.assigned_slave");
if (slaveId === null) { return; }
let connection = slaveConnections.get(slaveId);
@@ -529,7 +529,7 @@ class BaseConnection extends link.Link {
let controlConnections = new Array();
class ControlConnection extends BaseConnection {
constructor(registerData, connector, user) {
super('control', connector)
super("control", connector)
this._agent = registerData.agent;
this._version = registerData.version;
@@ -630,7 +630,7 @@ class ControlConnection extends BaseConnection {
throw new errors.RequestError(`Instance with ID ${message.data.instance_id} does not exist`);
}
if (instance.config.get('instance.assigned_slave') !== null) {
if (instance.config.get("instance.assigned_slave") !== null) {
await this.forwardRequestToInstance(message, request);
}
db.instances.delete(message.data.instance_id);
@@ -848,7 +848,7 @@ var slaveConnections = new Map();
*/
class SlaveConnection extends BaseConnection {
constructor(registerData, connector) {
super('slave', connector);
super("slave", connector);
this._agent = registerData.agent;
this._id = registerData.id;
@@ -1407,7 +1407,7 @@ function listen(server, ...args) {
// For reasons that defy common sense, the connection event has
// to be emitted explictly when using noServer.
wss.handleUpgrade(req, socket, head, (ws) => {
wss.emit('connection', ws, req);
wss.emit("connection", ws, req);
});
});
@@ -1417,9 +1417,9 @@ function listen(server, ...args) {
));
}
server.once('error', wrapError);
server.once("error", wrapError);
server.listen(...args, () => {
server.off('error', wrapError);
server.off("error", wrapError);
resolve();
});
});
@@ -1450,7 +1450,7 @@ async function startServer() {
process.title = "clusterioMaster";
// add better stack traces on promise rejection
process.on('unhandledRejection', r => console.log(r));
process.on("unhandledRejection", r => console.log(r));
// argument parsing
let args = yargs
@@ -1492,7 +1492,7 @@ async function startServer() {
await masterConfig.load(JSON.parse(await fs.readFile(masterConfigPath)));
} catch (err) {
if (err.code === 'ENOENT') {
if (err.code === "ENOENT") {
console.log("Config not found, initializing new config");
await masterConfig.init();
@@ -1555,7 +1555,7 @@ async function startServer() {
// If we get here the command was run
let secondSigint = false
process.on('SIGINT', () => {
process.on("SIGINT", () => {
if (secondSigint) {
console.log("Caught second interrupt, terminating immediately");
process.exit(1);
@@ -1567,28 +1567,28 @@ async function startServer() {
});
// terminal closed
process.on('SIGHUP', () => {
process.on("SIGHUP", () => {
// No graceful cleanup, no warning out (stdout is likely closed.)
// Don't close the terminal with the clusterio master in it.
process.exit(1);
});
await fs.ensureDir(masterConfig.get('master.database_directory'));
await fs.ensureDir(masterConfig.get("master.database_directory"));
db.slaves = await loadMap(masterConfig.get('master.database_directory'), "slaves.json");
db.instances = await loadInstances(masterConfig.get('master.database_directory'), "instances.json");
db.slaves = await loadMap(masterConfig.get("master.database_directory"), "slaves.json");
db.instances = await loadInstances(masterConfig.get("master.database_directory"), "instances.json");
await loadUsers(masterConfig.get("master.database_directory"), "users.json");
// Make sure we're actually going to listen on a port
let httpPort = masterConfig.get('master.http_port');
let httpsPort = masterConfig.get('master.https_port');
let httpPort = masterConfig.get("master.http_port");
let httpsPort = masterConfig.get("master.https_port");
if (!httpPort && !httpsPort) {
console.error("Error: at least one of http_port and https_port must be configured");
process.exit(1);
}
let tls_cert = masterConfig.get('master.tls_certificate');
let tls_key = masterConfig.get('master.tls_private_key');
let tls_cert = masterConfig.get("master.tls_certificate");
let tls_key = masterConfig.get("master.tls_private_key");
// Create a self signed certificate if the certificate files doesn't exist
if (httpsPort && !await fs.exists(tls_cert) && !await fs.exists(tls_key)) {
await generateSSLcert({
+4 -4
View File
@@ -10,10 +10,10 @@ module.exports = {
messages: {
chat: new link.Event({
type: 'global_chat:chat',
links: ['instance-slave', 'slave-master', 'master-slave', 'slave-instance'],
forwardTo: 'master',
broadcastTo: 'instance',
type: "global_chat:chat",
links: ["instance-slave", "slave-master", "master-slave", "slave-instance"],
forwardTo: "master",
broadcastTo: "instance",
eventProperties: {
"instance_name": { type: "string" },
"content": { type: "string" },
+5 -5
View File
@@ -1,9 +1,9 @@
const assert = require('assert').strict;
const assert = require("assert").strict;
const mock = require('../../../test/mock');
const lines = require('../../../test/lib/factorio/lines');
const instance = require('../instance');
const info = require('../info');
const mock = require("../../../test/mock");
const lines = require("../../../test/lib/factorio/lines");
const instance = require("../instance");
const info = require("../info");
describe("global_chat plugin", function() {
+2 -2
View File
@@ -1,5 +1,5 @@
// These are libraries that does not have any units test, they are
// required here in order to track coverage for them.
require('../instance');
require('../master');
require("../instance");
require("../master");
+7 -7
View File
@@ -1,28 +1,28 @@
const plugin = require('lib/plugin');
const { Gauge } = require('lib/prometheus');
const plugin = require("lib/plugin");
const { Gauge } = require("lib/prometheus");
const instancePlayerCount = new Gauge(
"clusterio_statistics_exporter_instance_player_count", "Amount of players connected to this cluster",
{ labels: ['instance_id'] }
{ labels: ["instance_id"] }
);
const instanceGameTicksTotal = new Gauge(
"clusterio_statistics_exporter_instance_game_ticks_total", "Game tick an instance has progressed to",
{ labels: ['instance_id'] }
{ labels: ["instance_id"] }
);
const instanceForceFlowStatistics = new Gauge(
"clusterio_statistics_exporter_instance_force_flow_statistics", "Items/fluids/enemies/buildings produced/built/killed by a force",
{ labels: ['instance_id', 'force', 'statistic', 'direction', 'name'] },
{ labels: ["instance_id", "force", "statistic", "direction", "name"] },
);
const instanceGameFlowStatistics = new Gauge(
"clusterio_statistics_exporter_instance_game_flow_statistics", "Pollution produced/consumed in the game",
{ labels: ['instance_id', 'statistic', 'direction', 'name'] },
{ labels: ["instance_id", "statistic", "direction", "name"] },
);
class InstancePlugin extends plugin.BaseInstancePlugin {
async onMetrics() {
let string = await this.instance.server.sendRcon('/sc statistics_exporter.export()');
let string = await this.instance.server.sendRcon("/sc statistics_exporter.export()");
let stats;
try {
stats = JSON.parse(string);
+11 -11
View File
@@ -1,8 +1,8 @@
const assert = require('assert').strict;
const assert = require("assert").strict;
const mock = require('../../../test/mock');
const instance = require('../instance');
const info = require('../info');
const mock = require("../../../test/mock");
const instance = require("../instance");
const info = require("../info");
describe("statistics_exporter plugin", function() {
@@ -16,7 +16,7 @@ describe("statistics_exporter plugin", function() {
describe(".onMetrics()", function() {
it("should record statistics", async function() {
instancePlugin.instance.server.rconCommandResults.set(
'/sc statistics_exporter.export()',
"/sc statistics_exporter.export()",
JSON.stringify({
game_tick: 100,
player_count: 3,
@@ -39,19 +39,19 @@ describe("statistics_exporter plugin", function() {
await instancePlugin.onMetrics();
assert.equal(instance._instancePlayerCount.labels('7357').get(), 3);
assert.equal(instance._instanceGameTicksTotal.labels('7357').get(), 100);
assert.equal(instance._instancePlayerCount.labels("7357").get(), 3);
assert.equal(instance._instanceGameTicksTotal.labels("7357").get(), 100);
assert.equal(instance._instanceForceFlowStatistics.labels(
'7357', 'player', 'item_production_statistics', 'input', 'inserter').get(),
"7357", "player", "item_production_statistics", "input", "inserter").get(),
10);
assert.equal(instance._instanceGameFlowStatistics.labels(
'7357', 'pollution_statistics', 'input', 'boiler').get(),
"7357", "pollution_statistics", "input", "boiler").get(),
2000);
});
it("should pass on JSON parse errors", async function() {
let string = 'An error occured\n';
let string = "An error occured\n";
instancePlugin.instance.server.rconCommandResults.set(
'/sc statistics_exporter.export()', string
"/sc statistics_exporter.export()", string
);
let errorMessage;
+1 -1
View File
@@ -104,7 +104,7 @@ function doleDivider({
object.count /= ((_doleDivisionFactor[object.name]||0)+doleDivisionRetardation)/doleDivisionRetardation;
object.count = Math.round(object.count);
if (logItemTransfers) {
console.info(`Serving ${object.count}/${originalCount} ${object.name} from ${itemCount} ${object.name} with dole division factor ${(_doleDivisionFactor[object.name]||0)} (real=${((_doleDivisionFactor[object.name]||0)+doleDivisionRetardation)/doleDivisionRetardation}), item is ${itemCount > object.count?'stocked':'short'}.`);
console.info(`Serving ${object.count}/${originalCount} ${object.name} from ${itemCount} ${object.name} with dole division factor ${(_doleDivisionFactor[object.name]||0)} (real=${((_doleDivisionFactor[object.name]||0)+doleDivisionRetardation)/doleDivisionRetardation}), item is ${itemCount > object.count?"stocked":"short"}.`);
}
// Update existing items if item name already exists
+7 -7
View File
@@ -7,8 +7,8 @@ function drawcontents(data) {
// allow searching for multiple criteria separated by space
var searchArgs = document.querySelector("#search").value;
searchArgs = searchArgs.trim();
searchArgs = '(' + searchArgs.replace(/ +/g,")|(") + ')';
const search = new RegExp(searchArgs, 'i');
searchArgs = "(" + searchArgs.replace(/ +/g,")|(") + ")";
const search = new RegExp(searchArgs, "i");
data = data.filter(function(item) {
return search.test(item.name);
})
@@ -25,7 +25,7 @@ function drawcontents(data) {
let row = rows[i];
if(!row) {
row = document.createElement('tr');
row = document.createElement("tr");
row.innerHTML = "<td><div></div></td><td class=name></td><td class=count></td>";
table.appendChild(row);
}
@@ -51,13 +51,13 @@ function drawcontents(data) {
}
}
const name = row.querySelector('.name');
const name = row.querySelector(".name");
if(name.textContent !== localeName) {
name.textContent = localeName;
}
const count = row.querySelector('.count');
if(count.textContent !== ''+item.count) {
const count = row.querySelector(".count");
if(count.textContent !== ""+item.count) {
count.textContent = item.count;
}
});
@@ -93,6 +93,6 @@ function sortByKey(array, key) {
});
}
document.querySelector("#search").addEventListener('input', function() {
document.querySelector("#search").addEventListener("input", function() {
drawcontents();
});
+4 -4
View File
@@ -1,7 +1,7 @@
// These are libraries that does not have any units test, they are
// required here in order to track coverage for them.
require('../instance');
require('../master');
require('../dole');
require('../dole_nn_base');
require("../instance");
require("../master");
require("../dole");
require("../dole_nn_base");
+36 -36
View File
@@ -10,8 +10,8 @@
* @example
* node slave run
*/
const fs = require('fs-extra');
const path = require('path');
const fs = require("fs-extra");
const path = require("path");
const yargs = require("yargs");
const events = require("events");
const pidusage = require("pidusage");
@@ -22,14 +22,14 @@ const version = require("./package").version;
// internal libraries
const fileOps = require("lib/fileOps");
const hashFile = require('lib/hash').hashFile;
const hashFile = require("lib/hash").hashFile;
const factorio = require("lib/factorio");
const link = require("lib/link");
const plugin = require("lib/plugin");
const errors = require("lib/errors");
const prometheus = require('lib/prometheus');
const luaTools = require('lib/luaTools');
const config = require('lib/config');
const prometheus = require("lib/prometheus");
const luaTools = require("lib/luaTools");
const config = require("lib/config");
const instanceRconCommandsCounter = new prometheus.Counter(
@@ -104,7 +104,7 @@ const serverSettingsActions = {
*/
class Instance extends link.Link{
constructor(slave, connector, dir, factorioDir, instanceConfig) {
super('instance', 'slave', connector);
super("instance", "slave", connector);
link.attachAllMessages(this);
this._slave = slave;
this._dir = dir;
@@ -125,9 +125,9 @@ class Instance extends link.Link{
let serverOptions = {
version: this.config.get("factorio.version"),
gamePort: this.config.get('factorio.game_port'),
rconPort: this.config.get('factorio.rcon_port'),
rconPassword: this.config.get('factorio.rcon_password'),
gamePort: this.config.get("factorio.game_port"),
rconPort: this.config.get("factorio.rcon_port"),
rconPassword: this.config.get("factorio.rcon_password"),
};
this._running = false;
@@ -141,7 +141,7 @@ class Instance extends link.Link{
return originalSendRcon.call(this.server, ...args);
}
this.server.on('output', (output) => {
this.server.on("output", (output) => {
link.messages.instanceOutput.send(this, { instance_id: this.config.get("instance.id"), output })
plugin.invokeHook(this.plugins, "onOutput", output);
@@ -181,7 +181,7 @@ class Instance extends link.Link{
for (let collector of prometheus.defaultRegistry.collectors) {
if (
collector instanceof prometheus.ValueCollector
&& collector.metric.labels.includes('instance_id')
&& collector.metric.labels.includes("instance_id")
) {
collector.removeAll({ instance_id: String(this.config.get("instance.id")) });
}
@@ -320,7 +320,7 @@ class Instance extends link.Link{
// Use latest save if no save was specified
if (saveName === null) {
saveName = await fileOps.getNewestFile(
this.path("saves"), (name) => !name.endsWith('.tmp.zip')
this.path("saves"), (name) => !name.endsWith(".tmp.zip")
);
}
@@ -337,12 +337,12 @@ class Instance extends link.Link{
// Find plugin modules to patch in
let modules = new Map();
for (let [pluginName, plugin] of this.plugins) {
let modulePath = path.join('plugins', pluginName, 'module');
let modulePath = path.join("plugins", pluginName, "module");
if (!await fs.pathExists(modulePath)) {
continue;
}
let moduleJsonPath = path.join(modulePath, 'module.json');
let moduleJsonPath = path.join(modulePath, "module.json");
if (!await fs.pathExists(moduleJsonPath)) {
throw new Error(`Module for plugin ${pluginName} is missing module.json`);
}
@@ -354,7 +354,7 @@ class Instance extends link.Link{
module = Object.assign({
version: plugin.info.version,
dependencies: { 'clusterio': '*' },
dependencies: { "clusterio": "*" },
path: modulePath,
load: [],
require: [],
@@ -364,13 +364,13 @@ class Instance extends link.Link{
// Find stand alone modules to load
// XXX for now it's assumed all available modules should be loaded.
for (let entry of await fs.readdir('modules', { withFileTypes: true })) {
for (let entry of await fs.readdir("modules", { withFileTypes: true })) {
if (entry.isDirectory()) {
if (modules.has(entry.name)) {
throw new Error(`Module with name ${entry.name} already exists in a plugin`);
}
let moduleJsonPath = path.join('modules', entry.name, 'module.json');
let moduleJsonPath = path.join("modules", entry.name, "module.json");
if (!await fs.pathExists(moduleJsonPath)) {
throw new Error(`Module ${entry.name} is missing module.json`);
}
@@ -381,8 +381,8 @@ class Instance extends link.Link{
}
module = Object.assign({
path: path.join('modules', entry.name),
dependencies: { 'clusterio': '*' },
path: path.join("modules", entry.name),
dependencies: { "clusterio": "*" },
load: [],
require: [],
}, module);
@@ -402,7 +402,7 @@ class Instance extends link.Link{
* @param {String} saveName - Name of save game to load.
*/
async start(saveName) {
this.server.on('rcon-ready', () => {
this.server.on("rcon-ready", () => {
console.log("Clusterio | RCON connection established");
});
@@ -622,7 +622,7 @@ async function discoverInstances(instanceInfos, instancesDir, logger) {
class InstanceConnection extends link.Link {
constructor(connector, slave, instanceId) {
super('slave', 'instance', connector);
super("slave", "instance", connector);
this.slave = slave;
this.instanceId = instanceId;
this.plugins = new Map();
@@ -717,7 +717,7 @@ class Slave extends link.Link {
// I don't like God classes, but the alternative of putting all this state
// into global variables is not much better.
constructor(connector, slaveConfig, pluginInfos) {
super('slave', 'master', connector);
super("slave", "master", connector);
link.attachAllMessages(this);
this.pluginInfos = pluginInfos;
@@ -803,7 +803,7 @@ class Slave extends link.Link {
// For now add dashes until an unused directory name is found
let dir = path.join(this.config.get("slave.instances_directory"), name);
while (await fs.pathExists(dir)) {
dir += '-';
dir += "-";
}
return dir;
@@ -919,10 +919,10 @@ class Slave extends link.Link {
}
for await (let result of prometheus.defaultRegistry.collect()) {
if (result.metric.name.startsWith('process_')) {
if (result.metric.name.startsWith("process_")) {
results.push(prometheus.serializeResult(result, {
addLabels: { 'slave_id': String(this.config.get("slave.id")) },
metricName: result.metric.name.replace('process_', 'clusterio_slave_'),
addLabels: { "slave_id": String(this.config.get("slave.id")) },
metricName: result.metric.name.replace("process_", "clusterio_slave_"),
}));
} else {
@@ -1034,10 +1034,10 @@ function checkFilename(name) {
const oneToNine = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const badNames = [
// Relative path components
'.', '..',
".", "..",
// Reserved filenames in Windows
'CON', 'PRN', 'AUX', 'NUL',
"CON", "PRN", "AUX", "NUL",
...oneToNine.map(n => `COM${n}`),
...oneToNine.map(n => `LPT${n}`),
];
@@ -1099,7 +1099,7 @@ async function symlinkMods(instance, sharedMods, logger) {
let instanceModsEntries = new Set(await fs.readdir(instance.path("mods")));
for (let entry of await fs.readdir(sharedMods, { withFileTypes: true })) {
if (entry.isFile()) {
if (['.zip', '.dat'].includes(path.extname(entry.name))) {
if ([".zip", ".dat"].includes(path.extname(entry.name))) {
if (!instanceModsEntries.has(entry.name)) {
logger.log(`linking ${entry.name} from ${sharedMods}`);
let target = path.join(sharedMods, entry.name);
@@ -1130,17 +1130,17 @@ async function symlinkMods(instance, sharedMods, logger) {
async function startSlave() {
// add better stack traces on promise rejection
process.on('unhandledRejection', r => console.log(r));
process.on("unhandledRejection", r => console.log(r));
// argument parsing
const args = yargs
.scriptName("slave")
.usage("$0 <command> [options]")
.option('config', {
.option("config", {
nargs: 1,
describe: "slave config file to use",
default: 'config-slave.json',
type: 'string',
default: "config-slave.json",
type: "string",
})
.command("config", "Manage Slave config", config.configCommand)
.command("run", "Run slave")
@@ -1160,7 +1160,7 @@ async function startSlave() {
await slaveConfig.load(JSON.parse(await fs.readFile(args.config)));
} catch (err) {
if (err.code === 'ENOENT') {
if (err.code === "ENOENT") {
console.log("Config not found, initializing new config");
await slaveConfig.init();
@@ -1211,7 +1211,7 @@ async function startSlave() {
// Handle interrupts
let secondSigint = false
process.on('SIGINT', () => {
process.on("SIGINT", () => {
if (secondSigint) {
console.log("Caught second interrupt, terminating immediately");
process.exit(1);
+11 -11
View File
@@ -1,10 +1,10 @@
const assert = require('assert').strict;
const chalk = require('chalk');
const assert = require("assert").strict;
const chalk = require("chalk");
const errors = require('lib/errors');
const { testLines } = require('./lib/factorio/lines');
const clusterctl = require('../clusterctl.js');
const mock = require('./mock');
const errors = require("lib/errors");
const { testLines } = require("./lib/factorio/lines");
const clusterctl = require("../clusterctl.js");
const mock = require("./mock");
describe("clusterctl", function() {
@@ -24,13 +24,13 @@ describe("clusterctl", function() {
});
let mockConnector = new mock.MockConnector();
mockConnector.on('send', function(message) {
if (message.type === 'list_instances_request') {
this.emit('message', {
seq: 1, type: 'list_instances_response',
mockConnector.on("send", function(message) {
if (message.type === "list_instances_request") {
this.emit("message", {
seq: 1, type: "list_instances_response",
data: {
seq: message.seq,
list: [{ id: 57, assigned_slave: 4, name: 'Test Instance' }],
list: [{ id: 57, assigned_slave: 4, name: "Test Instance" }],
},
});
}
+2 -2
View File
@@ -1,8 +1,8 @@
const assert = require("assert").strict;
const fs = require("fs-extra");
const path = require("path");
const validateHTML = require('html5-validator');
const parallel = require('mocha.parallel');
const validateHTML = require("html5-validator");
const parallel = require("mocha.parallel");
const link = require("lib/link");
+6 -6
View File
@@ -32,7 +32,7 @@ describe("Integration of lib/factorio/server", function() {
await fs.ensureDir(writePath);
logFile = fs.createWriteStream(path.join(writePath, "log.txt"), "utf8");
server.on('output', function(output) {
server.on("output", function(output) {
logFile.write(JSON.stringify(output) + "\n");
});
@@ -119,7 +119,7 @@ describe("Integration of lib/factorio/server", function() {
log(".sendRcon()");
let result = await server.sendRcon("/sc rcon.print('success')");
assert.equal(result, 'success\n');
assert.equal(result, "success\n");
});
it("throws on non-empty response when enabled", async function() {
slowTest(this);
@@ -155,14 +155,14 @@ describe("Integration of lib/factorio/server", function() {
pass = true;
}
}
server.on('output', filter);
server.on("output", filter);
await server.startScenario("test_scenario");
log(".stop()");
await server.stop();
server.off('output', filter);
server.off("output", filter);
assert(pass, "server did not output line from test scenario");
});
});
@@ -191,7 +191,7 @@ describe("Integration of lib/factorio/server", function() {
await server.start("test.zip");
if (!server._rconReady) {
await events.once(server, 'rcon-ready');
await events.once(server, "rcon-ready");
}
server.sendRcon("/c while true do end").catch(() => {});
await new Promise((resolve) => setTimeout(resolve, 300));
@@ -210,7 +210,7 @@ describe("Integration of lib/factorio/server", function() {
log(".start() for kill detection");
let startPromise = server.start("test.zip");
server.once('output', () => server._server.kill('SIGKILL'));
server.once("output", () => server._server.kill("SIGKILL"));
await assert.rejects(
startPromise,
+37 -37
View File
@@ -19,14 +19,14 @@ describe("lib/database", function() {
it("should throw convert a map to an object", function() {
assert.deepEqual(
database.mapToObject(new Map([['a', 1], ['b', true]])),
{'a': 1, 'b': true}
database.mapToObject(new Map([["a", 1], ["b", true]])),
{"a": 1, "b": true}
);
});
});
describe("loadJsonAsMap()", function() {
let badTypes = ['null', 'array', 'number', 'string', 'boolean'];
let badTypes = ["null", "array", "number", "string", "boolean"];
for (let type of badTypes) {
it(`should reject on ${type} JSON`, async function() {
@@ -47,7 +47,7 @@ describe("lib/database", function() {
it("should work on object JSON", async function() {
assert.deepEqual(
await database.loadJsonAsMap(path.join("test", "file", "json", "load_map.json")),
new Map([['a', 1], ['b', true]])
new Map([["a", 1], ["b", true]])
);
});
@@ -67,7 +67,7 @@ describe("lib/database", function() {
await fs.unlink(testFile);
} catch (err) {
/* istanbul ignore if */
if (err.code !== 'ENOENT') {
if (err.code !== "ENOENT") {
throw err;
}
}
@@ -75,18 +75,18 @@ describe("lib/database", function() {
await deleteTestFile();
await database.saveMapAsJson(
testFile, new Map([['c', {}], ['d', "foo"]])
testFile, new Map([["c", {}], ["d", "foo"]])
);
assert.equal(
await fs.readFile(testFile, {encoding: 'utf-8'}),
await fs.readFile(testFile, {encoding: "utf-8"}),
'{\n "c": {},\n "d": "foo"\n}'
);
});
});
describe("loadJsonArrayAsMap()", function() {
let badTypes = ['null', 'object', 'number', 'string', 'boolean'];
let badTypes = ["null", "object", "number", "string", "boolean"];
for (let type of badTypes) {
it(`should reject on ${type} JSON`, async function() {
@@ -121,7 +121,7 @@ describe("lib/database", function() {
it("should work on array JSON", async function() {
assert.deepEqual(
await database.loadJsonArrayAsMap(path.join("test", "file", "json", "load_array_map.json")),
new Map([['a', {id: 'a'}], ['b', {id: 'b'}]])
new Map([["a", {id: "a"}], ["b", {id: "b"}]])
);
});
@@ -141,7 +141,7 @@ describe("lib/database", function() {
await fs.unlink(testFile);
} catch (err) {
/* istanbul ignore if */
if (err.code !== 'ENOENT') {
if (err.code !== "ENOENT") {
throw err;
}
}
@@ -149,11 +149,11 @@ describe("lib/database", function() {
await deleteTestFile();
await database.saveMapAsJsonArray(
testFile, new Map([['c', {id: 'c'}], ['d', {id: 'd'}]])
testFile, new Map([["c", {id: "c"}], ["d", {id: "d"}]])
);
assert.equal(
await fs.readFile(testFile, {encoding: 'utf-8'}),
await fs.readFile(testFile, {encoding: "utf-8"}),
'[\n {\n "id": "c"\n },\n {\n "id": "d"\n }\n]'
);
});
@@ -167,18 +167,18 @@ describe("lib/database", function() {
});
it("should restore the passed serialized database", function() {
let items = new database.ItemDatabase({'a': 1, 'b': 2});
assert.deepEqual(items._items, new Map([['a', 1], ['b', 2]]));
let items = new database.ItemDatabase({"a": 1, "b": 2});
assert.deepEqual(items._items, new Map([["a", 1], ["b", 2]]));
});
it("should throw on invalid serialized database", function() {
assert.throws(
() => new database.ItemDatabase({'a': NaN}),
() => new database.ItemDatabase({"a": NaN}),
new Error("count must be a number")
);
assert.throws(
() => new database.ItemDatabase({'a': 'a'}),
() => new database.ItemDatabase({"a": "a"}),
new Error("count must be a number")
);
});
@@ -186,32 +186,32 @@ describe("lib/database", function() {
describe(".serialize()", function() {
it("should return a serialized database", function() {
let items = new database.ItemDatabase({'a': 10});
assert.deepEqual(items.serialize(), {'a': 10});
let items = new database.ItemDatabase({"a": 10});
assert.deepEqual(items.serialize(), {"a": 10});
});
it("should remove zero count entries", function() {
let items = new database.ItemDatabase({'a': 0});
let items = new database.ItemDatabase({"a": 0});
assert.deepEqual(items.serialize(), {});
});
});
describe(".size", function() {
it("should give an approximate size of the database", function() {
let items = new database.ItemDatabase({'a': 10});
let items = new database.ItemDatabase({"a": 10});
assert.equal(items.size, 1);
});
});
describe(".getItemCount()", function() {
it("should return the count of the given item", function() {
let items = new database.ItemDatabase({'a': 10});
assert.equal(items.getItemCount('a'), 10);
let items = new database.ItemDatabase({"a": 10});
assert.equal(items.getItemCount("a"), 10);
});
it("should return zero if item does not exist", function() {
let items = new database.ItemDatabase();
assert.equal(items.getItemCount('b'), 0);
assert.equal(items.getItemCount("b"), 0);
});
it("should throw on invalid name", function() {
@@ -226,14 +226,14 @@ describe("lib/database", function() {
describe(".addItem()", function() {
it("should add a new item", function() {
let items = new database.ItemDatabase();
items.addItem('a', 10);
assert.deepEqual(items._items, new Map([['a', 10]]));
items.addItem("a", 10);
assert.deepEqual(items._items, new Map([["a", 10]]));
})
it("should add an existing item", function() {
let items = new database.ItemDatabase({'a': 10});
items.addItem('a', 10);
assert.deepEqual(items._items, new Map([['a', 20]]));
let items = new database.ItemDatabase({"a": 10});
items.addItem("a", 10);
assert.deepEqual(items._items, new Map([["a", 20]]));
})
it("should throw on invalid name", function() {
@@ -247,11 +247,11 @@ describe("lib/database", function() {
it("should throw on invalid count", function() {
let items = new database.ItemDatabase();
assert.throws(
() => items.addItem('a', NaN),
() => items.addItem("a", NaN),
new Error("count must be a number")
);
assert.throws(
() => items.addItem('a', "1"),
() => items.addItem("a", "1"),
new Error("count must be a number")
);
});
@@ -259,15 +259,15 @@ describe("lib/database", function() {
describe(".removeItem()", function() {
it("should remove an existing item", function() {
let items = new database.ItemDatabase({'a': 20});
items.removeItem('a', 10);
assert.deepEqual(items._items, new Map([['a', 10]]));
let items = new database.ItemDatabase({"a": 20});
items.removeItem("a", 10);
assert.deepEqual(items._items, new Map([["a", 10]]));
})
it("should turn a non-existing item negative", function() {
let items = new database.ItemDatabase();
items.removeItem('a', 10);
assert.deepEqual(items._items, new Map([['a', -10]]));
items.removeItem("a", 10);
assert.deepEqual(items._items, new Map([["a", -10]]));
})
it("should throw on invalid name", function() {
@@ -281,11 +281,11 @@ describe("lib/database", function() {
it("should throw on invalid count", function() {
let items = new database.ItemDatabase();
assert.throws(
() => items.removeItem('a', 'b'),
() => items.removeItem("a", "b"),
new Error("count must be a number")
);
assert.throws(
() => items.removeItem('a', "1"),
() => items.removeItem("a", "1"),
new Error("count must be a number")
);
});
+35 -35
View File
@@ -4,10 +4,10 @@ let testLines = new Map([
[
" 1.306 Info RemoteCommandProcessor.cpp:131: Starting RCON interface at port 4000",
{
format: 'seconds',
time: '1.306',
type: 'log',
level: 'Info',
format: "seconds",
time: "1.306",
type: "log",
level: "Info",
file: "RemoteCommandProcessor.cpp:131",
message: "Starting RCON interface at port 4000",
}
@@ -15,10 +15,10 @@ let testLines = new Map([
[
" 0.622 Warning FileUtil.cpp:527: test not found; using test.zip",
{
format: 'seconds',
time: '0.622',
type: 'log',
level: 'Warning',
format: "seconds",
time: "0.622",
type: "log",
level: "Warning",
file: "FileUtil.cpp:527",
message: "test not found; using test.zip",
}
@@ -26,10 +26,10 @@ let testLines = new Map([
[
" 0.554 Error Main.cpp:839: require_user_verification must be enabled for public games.",
{
format: 'seconds',
time: '0.554',
type: 'log',
level: 'Error',
format: "seconds",
time: "0.554",
type: "log",
level: "Error",
file: "Main.cpp:839",
message: "require_user_verification must be enabled for public games.",
}
@@ -37,27 +37,27 @@ let testLines = new Map([
[
" 640.910 Quitting: remote-quit.",
{
format: 'seconds',
time: '640.910',
type: 'generic',
format: "seconds",
time: "640.910",
type: "generic",
message: "Quitting: remote-quit.",
}
],
[
"1641.421 Goodbye",
{
format: 'seconds',
time: '1641.421',
type: 'generic',
format: "seconds",
time: "1641.421",
type: "generic",
message: "Goodbye",
}
],
[
"2019-01-20 10:30:04 [JOIN] User joined the game",
{
format: 'date',
time: '2019-01-20 10:30:04',
type: 'action',
format: "date",
time: "2019-01-20 10:30:04",
type: "action",
action: "JOIN",
message: "User joined the game",
}
@@ -65,9 +65,9 @@ let testLines = new Map([
[
"2019-01-20 10:30:07 [CHAT] User: chat message",
{
format: 'date',
time: '2019-01-20 10:30:07',
type: 'action',
format: "date",
time: "2019-01-20 10:30:07",
type: "action",
action: "CHAT",
message: "User: chat message",
}
@@ -75,9 +75,9 @@ let testLines = new Map([
[
"2019-01-20 10:30:14 [COMMAND] User (command): blah",
{
format: 'date',
time: '2019-01-20 10:30:14',
type: 'action',
format: "date",
time: "2019-01-20 10:30:14",
type: "action",
action: "COMMAND",
message: "User (command): blah",
}
@@ -85,18 +85,18 @@ let testLines = new Map([
[
"2019-01-20 10:30:14 Cannot execute command. Error: [string \"blah\"]:1: syntax error near <eof>",
{
format: 'date',
time: '2019-01-20 10:30:14',
type: 'generic',
format: "date",
time: "2019-01-20 10:30:14",
type: "generic",
message: "Cannot execute command. Error: [string \"blah\"]:1: syntax error near <eof>",
}
],
[
"2019-01-20 10:30:21 [LEAVE] User left the game",
{
format: 'date',
time: '2019-01-20 10:30:21',
type: 'action',
format: "date",
time: "2019-01-20 10:30:21",
type: "action",
action: "LEAVE",
message: "User left the game",
}
@@ -104,8 +104,8 @@ let testLines = new Map([
[
"Error while running event level::on_nth_tick(1)",
{
format: 'none',
type: 'generic',
format: "none",
type: "generic",
message: "Error while running event level::on_nth_tick(1)",
}
],
+30 -30
View File
@@ -50,20 +50,20 @@ describe("lib/factorio", function() {
describe("generateLoader()", function() {
let reference = [
'-- Auto generated scenario module loader created by Clusterio',
'-- Modifications to this file will be lost when loaded in Clusterio',
'clusterio_patch_number = 1',
'',
"-- Auto generated scenario module loader created by Clusterio",
"-- Modifications to this file will be lost when loaded in Clusterio",
"clusterio_patch_number = 1",
"",
'local event_handler = require("event_handler")',
'',
'-- Scenario modules',
"",
"-- Scenario modules",
'event_handler.add_lib(require("foo"))',
'',
'-- Clusterio modules',
"",
"-- Clusterio modules",
'event_handler.add_lib(require("modules/spam/bar"))',
'require("modules/spam/spam")',
'',
].join('\n');
"",
].join("\n");
let patchInfo = {
"patch_number": 1,
"scenario": { "modules": ["foo"] },
@@ -85,15 +85,15 @@ describe("lib/factorio", function() {
describe("reorderDependencies()", function() {
it("should reorder to satisfy simple dependency", function() {
let modules = [
{ name: 'a', version: '1.0.0', dependencies: {'b': '*'} },
{ name: 'b', version: '1.0.0', dependencies: {} },
{ name: "a", version: "1.0.0", dependencies: {"b": "*"} },
{ name: "b", version: "1.0.0", dependencies: {} },
];
factorio._reorderDependencies(modules);
assert(modules[0].name === 'b', "Dependency was not reorederd");
assert(modules[0].name === "b", "Dependency was not reorederd");
});
it("should throw on invalid version", function() {
let modules = [
{ name: 'a', version: 'foo', dependencies: {} },
{ name: "a", version: "foo", dependencies: {} },
];
assert.throws(
() => factorio._reorderDependencies(modules),
@@ -102,7 +102,7 @@ describe("lib/factorio", function() {
});
it("should throw on invalid version range", function() {
let modules = [
{ name: 'a', version: '1.0.0', dependencies: {'b': 'invalid'} },
{ name: "a", version: "1.0.0", dependencies: {"b": "invalid"} },
];
assert.throws(
() => factorio._reorderDependencies(modules),
@@ -111,16 +111,16 @@ describe("lib/factorio", function() {
});
it("should throw on missing dependency", function() {
let modules = [
{ name: 'a', version: '1.0.0', dependencies: {'b': '*'} },
{ name: "a", version: "1.0.0", dependencies: {"b": "*"} },
];
assert.throws(
() => factorio._reorderDependencies(modules),
new Error("Missing dependency b for module a")
);
modules = [
{ name: 'a', version: '1.0.0', dependencies: {'b': '*'} },
{ name: 'b', version: '1.0.0', dependencies: {'c': '*'} },
{ name: 'c', version: '1.0.0', dependencies: {'d': '*'} },
{ name: "a", version: "1.0.0", dependencies: {"b": "*"} },
{ name: "b", version: "1.0.0", dependencies: {"c": "*"} },
{ name: "c", version: "1.0.0", dependencies: {"d": "*"} },
];
assert.throws(
() => factorio._reorderDependencies(modules),
@@ -129,8 +129,8 @@ describe("lib/factorio", function() {
});
it("should throw on outdated dependency", function() {
let modules = [
{ name: 'a', version: '1.0.0', dependencies: {} },
{ name: 'b', version: '1.0.0', dependencies: {'a': '>=2'} },
{ name: "a", version: "1.0.0", dependencies: {} },
{ name: "b", version: "1.0.0", dependencies: {"a": ">=2"} },
];
assert.throws(
() => factorio._reorderDependencies(modules),
@@ -139,18 +139,18 @@ describe("lib/factorio", function() {
});
it("should throw on dependency loops", function() {
let modules = [
{ name: 'a', version: '1.0.0', dependencies: {'b': '*'} },
{ name: 'b', version: '1.0.0', dependencies: {'a': '*'} },
{ name: "a", version: "1.0.0", dependencies: {"b": "*"} },
{ name: "b", version: "1.0.0", dependencies: {"a": "*"} },
];
assert.throws(
() => factorio._reorderDependencies(modules),
new Error("Module dependency loop detected: a -> b -> a")
);
modules = [
{ name: 'd', version: '1.0.0', dependencies: {'b': '*'} },
{ name: 'a', version: '1.0.0', dependencies: {'b': '*'} },
{ name: 'b', version: '1.0.0', dependencies: {'c': '*'} },
{ name: 'c', version: '1.0.0', dependencies: {'a': '*'} },
{ name: "d", version: "1.0.0", dependencies: {"b": "*"} },
{ name: "a", version: "1.0.0", dependencies: {"b": "*"} },
{ name: "b", version: "1.0.0", dependencies: {"c": "*"} },
{ name: "c", version: "1.0.0", dependencies: {"a": "*"} },
];
assert.throws(
() => factorio._reorderDependencies(modules),
@@ -170,7 +170,7 @@ describe("lib/factorio", function() {
}
}
let names = ['a', 'b', 'c'];
let names = ["a", "b", "c"];
let successCount = 0;
const bitCount = names.length * (names.length - 1);
for (let i=0; i < 2**bitCount; i++) {
@@ -186,10 +186,10 @@ describe("lib/factorio", function() {
let dependencies = {};
for (let k=0; k < names.length - 1; k++) {
if (bits[k + j * (names.length - 1)]) {
dependencies[names[k + (k >= j)]] = '*';
dependencies[names[k + (k >= j)]] = "*";
}
}
modules.push({ name, version: '1.0.0', dependencies });
modules.push({ name, version: "1.0.0", dependencies });
}
let success = false;
try {
+11 -11
View File
@@ -157,8 +157,8 @@ describe("lib/factorio/server", function() {
describe("parseOutput()", function() {
it("should parse the test lines", function() {
for (let [line, reference] of testLines) {
reference.source = 'test';
let output = factorio._parseOutput(line, 'test');
reference.source = "test";
let output = factorio._parseOutput(line, "test");
delete output.received;
assert.deepEqual(output, reference);
}
@@ -187,46 +187,46 @@ describe("lib/factorio/server", function() {
describe("._handleIpc()", function() {
it("should emit the correct ipc event", async function() {
let waiter = events.once(server, 'ipc-channel');
let waiter = events.once(server, "ipc-channel");
await server._handleIpc(Buffer.from('\f$ipc:channel?j"value"'));
let result = await waiter;
assert.equal(result[0], "value");
});
it("should handle special characters in channel name", async function() {
let waiter = events.once(server, 'ipc-$ ?\x00\x0a:');
let waiter = events.once(server, "ipc-$ ?\x00\x0a:");
await server._handleIpc(Buffer.from('\f$ipc:$ \\x3f\\x00\\x0a:?j"value"'));
let result = await waiter;
assert.equal(result[0], "value");
});
it("should throw on malformed ipc line", async function() {
await assert.rejects(
server._handleIpc(Buffer.from('\f$ipc:blah')),
server._handleIpc(Buffer.from("\f$ipc:blah")),
new Error('Malformed IPC line "\f$ipc:blah"')
);
})
it("should throw on unknown type", async function() {
await assert.rejects(
server._handleIpc(Buffer.from('\f$ipc:channel??')),
server._handleIpc(Buffer.from("\f$ipc:channel??")),
new Error("Unknown IPC type '?'")
);
})
it("should throw on unknown file type", async function() {
await assert.rejects(
server._handleIpc(Buffer.from('\f$ipc:channel?ffoo.invalid')),
server._handleIpc(Buffer.from("\f$ipc:channel?ffoo.invalid")),
new Error("Unknown IPC file format 'invalid'")
);
})
it("should throw on file name with slash", async function() {
await assert.rejects(
server._handleIpc(Buffer.from('\f$ipc:channel?fa/b')),
server._handleIpc(Buffer.from("\f$ipc:channel?fa/b")),
new Error("Invalid IPC file name 'a/b'")
);
})
it("should load and delete json file", async function() {
let filePath = server.writePath('script-output', 'data.json');
let filePath = server.writePath("script-output", "data.json");
await fs.outputFile(filePath, '{"data":"spam"}');
let waiter = events.once(server, 'ipc-channel');
await server._handleIpc(Buffer.from('\f$ipc:channel?fdata.json'));
let waiter = events.once(server, "ipc-channel");
await server._handleIpc(Buffer.from("\f$ipc:channel?fdata.json"));
let result = await waiter;
assert.deepEqual(result[0], { "data": "spam" });
assert(!await fs.pathExists(filePath), "File was not deleted");
+4 -4
View File
@@ -1,8 +1,8 @@
const assert = require('assert').strict;
const fs = require('fs-extra');
const path = require('path');
const assert = require("assert").strict;
const fs = require("fs-extra");
const path = require("path");
const fileOps = require('lib/fileOps');
const fileOps = require("lib/fileOps");
describe("fileOps.js", function(){
let baseDir = path.join("temp", "test", "fileOps");
+5 -5
View File
@@ -1,9 +1,9 @@
const assert = require('assert').strict;
const fs = require('fs');
const path = require('path');
const stream = require('stream');
const assert = require("assert").strict;
const fs = require("fs");
const path = require("path");
const stream = require("stream");
const hash = require('lib/hash');
const hash = require("lib/hash");
describe("lib/hash", function() {
+12 -12
View File
@@ -1,8 +1,8 @@
const assert = require('assert').strict;
const events = require('events');
const assert = require("assert").strict;
const events = require("events");
const mock = require('../../mock');
const link = require('lib/link');
const mock = require("../../mock");
const link = require("lib/link");
describe("lib/link/connectors", function() {
@@ -33,7 +33,7 @@ describe("lib/link/connectors", function() {
});
describe("class WebSocketClientConnector", function() {
let testConnector = new link.WebSocketClientConnector('url', 1);
let testConnector = new link.WebSocketClientConnector("url", 1);
testConnector._socket = new mock.MockSocket();
describe(".register()", function() {
@@ -49,10 +49,10 @@ describe("lib/link/connectors", function() {
it("calls send on the socket", function() {
testConnector._state = "handshake";
testConnector._socket.sentMessages = [];
testConnector.sendHandshake('test', { test: true });
testConnector.sendHandshake("test", { test: true });
assert.deepEqual(
testConnector._socket.sentMessages.map(JSON.parse),
[{ seq: null, type: 'test', data: { test: true }}]
[{ seq: null, type: "test", data: { test: true }}]
);
});
});
@@ -61,10 +61,10 @@ describe("lib/link/connectors", function() {
it("calls send on the socket", function() {
testConnector._state = "connected";
testConnector._socket.sentMessages = [];
let seq = testConnector.send('test', { test: true });
let seq = testConnector.send("test", { test: true });
assert.deepEqual(
testConnector._socket.sentMessages.map(JSON.parse),
[{ seq, type: 'test', data: { test: true }}]
[{ seq, type: "test", data: { test: true }}]
);
});
});
@@ -86,13 +86,13 @@ describe("lib/link/connectors", function() {
it("should call register on hello", function() {
let called = false;
testConnector.register = () => { called = true; };
testConnector._processHandshake({ seq: 1, type: 'hello', data: { version: "test", plugins: {} }});
testConnector._processHandshake({ seq: 1, type: "hello", data: { version: "test", plugins: {} }});
assert(called, "register was not called");
});
it("should emit connect on ready", async function() {
let result = events.once(testConnector, "connect");
testConnector._processHandshake(
{ seq: 1, type: 'ready', data: { session_token: "x", heartbeat_interval: 10 }}
{ seq: 1, type: "ready", data: { session_token: "x", heartbeat_interval: 10 }}
);
await result;
clearInterval(testConnector._heartbeatId);
@@ -121,7 +121,7 @@ describe("lib/link/connectors", function() {
it("should emit message on message in connected state", async function() {
testConnector._socket.sentMessages = [];
testConnector._state = "connected";
let result = events.once(testConnector, 'message');
let result = events.once(testConnector, "message");
testConnector._socket.events.get("message")('{"message":true}');
assert.deepEqual(await result, [{ message: true }]);
});
+42 -42
View File
@@ -1,5 +1,5 @@
const assert = require('assert').strict;
const events = require('events');
const assert = require("assert").strict;
const events = require("events");
const link = require("lib/link");
const errors = require("lib/errors");
@@ -14,13 +14,13 @@ describe("lib/link/link", function() {
before(function() {
testConnector = new mock.MockConnector();
testLink = new link.Link('source', 'target', testConnector);
testLink.setValidator('simple', schema.compile({
testLink = new link.Link("source", "target", testConnector);
testLink.setValidator("simple", schema.compile({
properties: {
"data": {
type: 'object',
type: "object",
properties: {
"string": { type: 'string' },
"string": { type: "string" },
},
},
},
@@ -28,20 +28,20 @@ describe("lib/link/link", function() {
});
it("should emitt error processing message to connector", async function() {
testLink.setHandler('throws', () => { throw new Error("Handler error"); }, () => true);
let result = events.once(testConnector, 'message');
testConnector.emit('message', { seq: 1, type: 'throws', data: {}});
testLink.setHandler("throws", () => { throw new Error("Handler error"); }, () => true);
let result = events.once(testConnector, "message");
testConnector.emit("message", { seq: 1, type: "throws", data: {}});
await assert.rejects(result, new Error("Handler error"));
});
describe(".setValidator()", function() {
it("should set the validator", function() {
testLink.setValidator('test', () => true);
assert(testLink._validators.has('test'), "validator was not added");
testLink.setValidator("test", () => true);
assert(testLink._validators.has("test"), "validator was not added");
});
it("should throw on duplicated validator", function() {
assert.throws(
() => testLink.setValidator('test', () => true),
() => testLink.setValidator("test", () => true),
new Error("test already has a validator")
);
});
@@ -50,18 +50,18 @@ describe("lib/link/link", function() {
describe(".setHandler()", function() {
it("should throw if validator is not passed", function() {
assert.throws(
() => testLink.setHandler('no_validator_test', (message) => {}),
() => testLink.setHandler("no_validator_test", (message) => {}),
new Error("validator is required")
);
});
it("should set the handler", function() {
let handler = (message) => {};
testLink.setHandler('handler_test', handler, (message) => true);
assert.equal(testLink._handlers.get('handler_test'), handler);
testLink.setHandler("handler_test", handler, (message) => true);
assert.equal(testLink._handlers.get("handler_test"), handler);
});
it("should throw on duplicated handler", function() {
assert.throws(
() => testLink.setHandler('handler_test', (message) => {}),
() => testLink.setHandler("handler_test", (message) => {}),
new Error("handler_test already has a handler")
);
});
@@ -76,19 +76,19 @@ describe("lib/link/link", function() {
});
it("should throw on message without validator", function() {
assert.throws(
() => testLink.processMessage({ seq: 1, type: 'no_validator', data: {} }),
() => testLink.processMessage({ seq: 1, type: "no_validator", data: {} }),
new errors.InvalidMessage("No validator for no_validator on source-target")
);
});
it("should throw on message failing validation", function() {
assert.throws(
() => testLink.processMessage({ seq: 1, type: 'simple', data: { string: 1 }}),
() => testLink.processMessage({ seq: 1, type: "simple", data: { string: 1 }}),
{ message: "Validation failed for simple" }
);
});
it("should throw on unhandled message", function() {
assert.throws(
() => testLink.processMessage({ seq: 1, type: 'simple', data: { string: "a" }}),
() => testLink.processMessage({ seq: 1, type: "simple", data: { string: "a" }}),
new errors.InvalidMessage("Unhandled message simple")
);
});
@@ -97,16 +97,16 @@ describe("lib/link/link", function() {
describe("._processHandler()", function() {
it("should call the handler", function() {
let handled = [];
testLink.setHandler('handled', (message) => handled.push(message), (message) => true)
testLink._processHandler({ seq: 1, type: 'handled', data: { test: "foo" } });
assert.deepEqual(handled, [{ seq: 1, type: 'handled', data: { test: "foo" } }]);
testLink.setHandler("handled", (message) => handled.push(message), (message) => true)
testLink._processHandler({ seq: 1, type: "handled", data: { test: "foo" } });
assert.deepEqual(handled, [{ seq: 1, type: "handled", data: { test: "foo" } }]);
});
it("should return true if handled", function() {
let result = testLink._processHandler({ seq: 1, type: 'handled', data: {} });
let result = testLink._processHandler({ seq: 1, type: "handled", data: {} });
assert.equal(result, true);
});
it("should return false if not handled", function() {
let result = testLink._processHandler({ seq: 1, type: 'not_handled', data: {} });
let result = testLink._processHandler({ seq: 1, type: "not_handled", data: {} });
assert.equal(result, false);
});
});
@@ -114,62 +114,62 @@ describe("lib/link/link", function() {
describe("._processWaiters()", function() {
it("should call waiters", async function() {
let waiter = new Promise(resolve => {
testLink._waiters.set('test', [{ resolve, data: {} }]);
testLink._waiters.set("test", [{ resolve, data: {} }]);
});
assert(
testLink._processWaiters({ type: 'test', seq: 4, data: {} }),
testLink._processWaiters({ type: "test", seq: 4, data: {} }),
"Waiter was not processed"
);
assert.deepEqual(await waiter, { type: 'test', seq: 4, data: {} });
assert.deepEqual(await waiter, { type: "test", seq: 4, data: {} });
});
it("should filter on data", async function() {
let waiter = new Promise(resolve => {
testLink._waiters.set('test', [{ resolve, data: { a: 1, b: 2 } }]);
testLink._waiters.set("test", [{ resolve, data: { a: 1, b: 2 } }]);
});
assert(
!testLink._processWaiters({ type: 'test', seq: 4, data: {} }),
!testLink._processWaiters({ type: "test", seq: 4, data: {} }),
"Incorrectly matched empty message"
);
assert(
!testLink._processWaiters({ type: 'test', seq: 4, data: { a: 1, b: 0 } }),
!testLink._processWaiters({ type: "test", seq: 4, data: { a: 1, b: 0 } }),
"Incorrectly matched message with wrong data"
);
assert(
testLink._processWaiters({ type: 'test', seq: 4, data: { a: 1, b: 2, c: 3 } }),
testLink._processWaiters({ type: "test", seq: 4, data: { a: 1, b: 2, c: 3 } }),
"Did not match correct message"
);
assert.deepEqual(await waiter, { type: 'test', seq: 4, data: { a: 1, b: 2, c: 3 } });
assert.deepEqual(await waiter, { type: "test", seq: 4, data: { a: 1, b: 2, c: 3 } });
});
});
describe(".waitFor()", function() {
before(function() {
testLink.setValidator('waiter', (message) => true);
testLink.setValidator("waiter", (message) => true);
});
it("should throw on missing validator", async function() {
await assert.rejects(
testLink.waitFor('no_validator', {}),
testLink.waitFor("no_validator", {}),
new Error("No validator for no_validator on source-target")
);
});
it("should wait for a given message", async function() {
let result = testLink.waitFor('waiter', {});
let result = testLink.waitFor("waiter", {});
assert(
testLink._processWaiters({ type: 'waiter', seq: 5, data: {} }),
testLink._processWaiters({ type: "waiter", seq: 5, data: {} }),
"Did not proccess waiter"
);
assert.deepEqual(await result, { type: 'waiter', seq: 5, data: {} });
assert.deepEqual(await result, { type: "waiter", seq: 5, data: {} });
});
it("should handle multiple waiters", async function() {
let result1 = testLink.waitFor('waiter', {});
let result2 = testLink.waitFor('waiter', {});
let result1 = testLink.waitFor("waiter", {});
let result2 = testLink.waitFor("waiter", {});
assert(
testLink._processWaiters({ type: 'waiter', seq: 5, data: {} }),
testLink._processWaiters({ type: "waiter", seq: 5, data: {} }),
"Did not proccess waiter"
);
assert.deepEqual(await result1, { type: 'waiter', seq: 5, data: {} });
assert.deepEqual(await result2, { type: 'waiter', seq: 5, data: {} });
assert.deepEqual(await result1, { type: "waiter", seq: 5, data: {} });
assert.deepEqual(await result2, { type: "waiter", seq: 5, data: {} });
});
});
});
+21 -21
View File
@@ -1,21 +1,21 @@
const assert = require('assert').strict;
const assert = require("assert").strict;
const link = require('lib/link');
const errors = require('lib/errors');
const mock = require('../../mock');
const link = require("lib/link");
const errors = require("lib/errors");
const mock = require("../../mock");
describe("lib/link/messages", function() {
let testSourceLink = new link.Link('source', 'target', new mock.MockConnector());
let testTargetLink = new link.Link('target', 'source', new mock.MockConnector());
let testSourceLink = new link.Link("source", "target", new mock.MockConnector());
let testTargetLink = new link.Link("target", "source", new mock.MockConnector());
let lastTargetSent;
testTargetLink.send = (type, data) => { lastTargetSent = { type, data }; };
describe("class Request", function() {
let testRequest = new link.Request({
type: 'test',
links: ['source-target'],
type: "test",
links: ["source-target"],
requestProperties: {
"test": { type: "string" },
},
@@ -24,7 +24,7 @@ describe("lib/link/messages", function() {
describe("constructor", function() {
it("should throw on invalid forwardTo", function() {
assert.throws(
() => new link.Request({ links: [], forwardTo: 'invalid'}),
() => new link.Request({ links: [], forwardTo: "invalid"}),
new Error("Invalid forwardTo value invalid")
);
});
@@ -33,7 +33,7 @@ describe("lib/link/messages", function() {
describe(".attach()", function() {
it("should attach validator to a source link", function() {
testRequest.attach(testSourceLink);
assert(testSourceLink._validators.has('test_response'), "Validator was not set");
assert(testSourceLink._validators.has("test_response"), "Validator was not set");
});
it("should throw if missing handler on target link", function() {
assert.throws(
@@ -45,16 +45,16 @@ describe("lib/link/messages", function() {
let handlerResult;
it("should attach handler to a target link", function() {
testRequest.attach(testTargetLink, async (message) => handlerResult );
assert(testTargetLink._handlers.has('test_request'), "Handler was not set");
assert(testTargetLink._handlers.has("test_request"), "Handler was not set");
});
it("should send result of calling the handler", async function() {
handlerResult = { test: "handler" };
testTargetLink._handlers.get('test_request')({ seq: 2 });
testTargetLink._handlers.get("test_request")({ seq: 2 });
let result = await new Promise(resolve => {
testTargetLink.connector.send = (type, data) => resolve({ type, data });
});
assert.deepEqual(result, {
type: 'test_response',
type: "test_response",
data: {
test: "handler",
seq: 2,
@@ -63,12 +63,12 @@ describe("lib/link/messages", function() {
});
it("should implicitly send an empty object on empty return", async function() {
handlerResult = undefined;
testTargetLink._handlers.get('test_request')({ seq: 2 });
testTargetLink._handlers.get("test_request")({ seq: 2 });
let result = await new Promise(resolve => {
testTargetLink.connector.send = (type, data) => resolve({ type, data });
});
assert.deepEqual(result, {
type: 'test_response',
type: "test_response",
data: {
seq: 2,
},
@@ -87,7 +87,7 @@ describe("lib/link/messages", function() {
};
assert.deepEqual(
await testRequest.send(testSourceLink, { test: "request" }),
{ type: 'test_response', request: { type: 'test_request', data: {test: "request" }}}
{ type: "test_response", request: { type: "test_request", data: {test: "request" }}}
);
delete testSourceLink.connector.send;
delete testSourceLink.waitFor;
@@ -107,8 +107,8 @@ describe("lib/link/messages", function() {
describe("class Event", function() {
let testEvent = new link.Event({
type: 'test',
links: ['source-target'],
type: "test",
links: ["source-target"],
eventProperties: {
"test": { type: "string" },
},
@@ -117,13 +117,13 @@ describe("lib/link/messages", function() {
describe("constructor", function() {
it("should throw on invalid forwardTo", function() {
assert.throws(
() => new link.Event({ forwardTo: 'invalid'}),
() => new link.Event({ forwardTo: "invalid"}),
new Error("Invalid forwardTo value invalid")
);
});
it("should throw on invalid broadcastTo", function() {
assert.throws(
() => new link.Event({ broadcastTo: 'invalid'}),
() => new link.Event({ broadcastTo: "invalid"}),
new Error("Invalid broadcastTo value invalid")
);
});
@@ -139,7 +139,7 @@ describe("lib/link/messages", function() {
let called = false;
it("should attach handler and validator to a target link", function() {
testEvent.attach(testTargetLink, async (message) => { called = true; });
assert(testTargetLink._validators.has('test_event'), "Validator was not set");
assert(testTargetLink._validators.has("test_event"), "Validator was not set");
});
it("should call the attached event handler", function() {
testTargetLink._handlers.get("test_event")();
+2 -2
View File
@@ -1,6 +1,6 @@
const assert = require('assert').strict;
const assert = require("assert").strict;
const luaTools = require('lib/luaTools');
const luaTools = require("lib/luaTools");
describe("lib/luaTools", function() {
+2 -2
View File
@@ -1,5 +1,5 @@
var assert = require('assert');
var objectOps = require('lib/objectOps');
var assert = require("assert");
var objectOps = require("lib/objectOps");
describe("objectOps.js", function(){
/*describe("objectOps.clone()", function(){
+21 -21
View File
@@ -1,11 +1,11 @@
const assert = require('assert').strict;
const fs = require('fs-extra');
const path = require('path');
const assert = require("assert").strict;
const fs = require("fs-extra");
const path = require("path");
const mock = require('../mock');
const link = require('lib/link');
const plugin = require('lib/plugin');
const errors = require('lib/errors');
const mock = require("../mock");
const link = require("lib/link");
const plugin = require("lib/plugin");
const errors = require("lib/errors");
describe("lib/plugin", function() {
@@ -43,26 +43,26 @@ describe("lib/plugin", function() {
describe("loadPluginInfos()", function() {
let baseDir = path.join("temp", "test", "plugin");
let emptyDir = path.join(baseDir, 'emptyDir');
let emptyPlugin = path.join(baseDir, 'emptyPlugin');
let testPlugin = path.join(baseDir, 'testPlugin');
let brokenPlugin = path.join(baseDir, 'brokenPlugin');
let invalidPlugin = path.join(baseDir, 'invalidPlugin');
let emptyDir = path.join(baseDir, "emptyDir");
let emptyPlugin = path.join(baseDir, "emptyPlugin");
let testPlugin = path.join(baseDir, "testPlugin");
let brokenPlugin = path.join(baseDir, "brokenPlugin");
let invalidPlugin = path.join(baseDir, "invalidPlugin");
before(async function() {
await fs.ensureDir(emptyDir);
await fs.ensureDir(path.join(emptyPlugin, 'empty'));
await fs.ensureDir(path.join(emptyPlugin, "empty"));
async function writePlugin(pluginPath, name, infoName = name) {
await fs.outputFile(
path.join(pluginPath, name, 'info.js'),
path.join(pluginPath, name, "info.js"),
`module.exports = { name: "${infoName}" };`
);
}
await writePlugin(testPlugin, 'test');
await writePlugin(brokenPlugin, 'broken');
await fs.outputFile(path.join(brokenPlugin, 'broken', 'info.js'), "Syntax Error");
await writePlugin(invalidPlugin, 'invalid', 'wrong');
await writePlugin(testPlugin, "test");
await writePlugin(brokenPlugin, "broken");
await fs.outputFile(path.join(brokenPlugin, "broken", "info.js"), "Syntax Error");
await writePlugin(invalidPlugin, "invalid", "wrong");
});
it("should return an empty array for an empty directory", async function() {
@@ -74,7 +74,7 @@ describe("lib/plugin", function() {
it("should discover test plugin", async function() {
assert.deepEqual(
await plugin.loadPluginInfos(testPlugin),
[{ name: 'test' }]
[{ name: "test" }]
);
});
it("should reject on broken plugin", async function() {
@@ -91,12 +91,12 @@ describe("lib/plugin", function() {
});
after(async function() {
await fs.unlink(path.join(brokenPlugin, 'broken', 'info.js'));
await fs.unlink(path.join(brokenPlugin, "broken", "info.js"));
});
});
describe("attachPluginMessages()", function() {
let mockLink = new link.Link('source', 'target', new mock.MockConnector());
let mockLink = new link.Link("source", "target", new mock.MockConnector());
let mockEvent = new link.Event({ type: "test:test", links: ["target-source"] });
it("should accept pluginInfo without messages", function() {
plugin.attachPluginMessages(mockLink, {}, null);
+89 -89
View File
@@ -1,6 +1,6 @@
const assert = require('assert').strict;
const assert = require("assert").strict;
const prometheus = require('lib/prometheus');
const prometheus = require("lib/prometheus");
describe("lib/prometheus", function() {
@@ -105,22 +105,22 @@ describe("lib/prometheus", function() {
describe("class Counter", function() {
let counter;
beforeEach(function() {
counter = new prometheus.Counter('test', "Help", { register: false });
counter = new prometheus.Counter("test", "Help", { register: false });
});
describe("constructor", function() {
it("should be initialized to 0", function() {
assert.equal(counter._values.get(''), 0);
assert.equal(counter._values.get(""), 0);
});
});
describe(".inc()", function() {
it("should increment the counter by 1 by default", function() {
counter.inc();
assert.equal(counter._values.get(''), 1);
assert.equal(counter._values.get(""), 1);
});
it("should increment the counter by specified value", function() {
counter.inc(3.2);
assert.equal(counter._values.get(''), 3.2);
assert.equal(counter._values.get(""), 3.2);
});
it("should throw if value is negative", function() {
assert.throws(
@@ -146,53 +146,53 @@ describe("lib/prometheus", function() {
describe("class Gauge", function() {
let gauge;
beforeEach(function() {
gauge = new prometheus.Gauge('test', "Help", { register: false });
gauge = new prometheus.Gauge("test", "Help", { register: false });
});
describe("constructor", function() {
it("should be initialized to 0", function() {
assert.equal(gauge._values.get(''), 0);
assert.equal(gauge._values.get(""), 0);
});
});
describe(".inc()", function() {
it("should increment the gauge by 1 by default", function() {
gauge.inc();
assert.equal(gauge._values.get(''), 1);
assert.equal(gauge._values.get(""), 1);
});
it("should increment the gauge by specified value", function() {
gauge.inc(3.2);
assert.equal(gauge._values.get(''), 3.2);
assert.equal(gauge._values.get(""), 3.2);
});
it("should decrement on negative value", function() {
gauge.inc(-2);
assert.equal(gauge._values.get(''), -2);
assert.equal(gauge._values.get(""), -2);
});
});
describe(".dec()", function() {
it("should decrement the gauge by 1 by default", function() {
gauge.dec();
assert.equal(gauge._values.get(''), -1);
assert.equal(gauge._values.get(""), -1);
});
it("should decrement the gauge by specified value", function() {
gauge.dec(3.2);
assert.equal(gauge._values.get(''), -3.2);
assert.equal(gauge._values.get(""), -3.2);
});
it("should increment on negative value", function() {
gauge.dec(-2);
assert.equal(gauge._values.get(''), 2);
assert.equal(gauge._values.get(""), 2);
});
});
describe(".set()", function() {
it("should set the gauge to the specified value", function() {
gauge.set(7);
assert.equal(gauge._values.get(''), 7);
assert.equal(gauge._values.get(""), 7);
});
});
describe(".setToCurrentTime()", function() {
it("should set the gauge to current unix time in seconds", function() {
gauge.setToCurrentTime();
assert(
Math.abs(gauge._values.get('') - Date.now() / 1000) < 1,
Math.abs(gauge._values.get("") - Date.now() / 1000) < 1,
"value set is not close to the current unix time"
);
});
@@ -215,7 +215,7 @@ describe("lib/prometheus", function() {
for (let name of ["", " ", "0a", "$a", "a:"]) {
assert.throws(
() => new prometheus.Gauge(
'test', "Help", { register: false, labels: [name] }
"test", "Help", { register: false, labels: [name] }
),
new Error(`Invalid label '${name}'`)
)
@@ -243,7 +243,7 @@ describe("lib/prometheus", function() {
describe(".get()", function() {
it("should return the current value", function() {
let gauge = new prometheus.Gauge('test', "Help", { register: false });
let gauge = new prometheus.Gauge("test", "Help", { register: false });
gauge.set(11);
assert.equal(gauge.get(), 11);
});
@@ -253,7 +253,7 @@ describe("lib/prometheus", function() {
let gauge;
beforeEach(function() {
gauge = new prometheus.Gauge(
'test', "Help", { register: false, labels: ['a', 'b'] }
"test", "Help", { register: false, labels: ["a", "b"] }
);
});
it("should require all labels set at creation", function() {
@@ -266,15 +266,15 @@ describe("lib/prometheus", function() {
new Error("Missing label 'a'")
);
assert.throws(
() => gauge.labels({a: '1', b: '2', c: '3'}),
() => gauge.labels({a: "1", b: "2", c: "3"}),
new Error("Extra label 'c'")
);
assert.throws(
() => gauge.labels('1'),
() => gauge.labels("1"),
new Error("Missing label 'b'")
);
assert.throws(
() => gauge.labels('1', '2', '3'),
() => gauge.labels("1", "2", "3"),
new Error("Extra positional label")
);
});
@@ -289,39 +289,39 @@ describe("lib/prometheus", function() {
);
});
it("should initialize a value for the label set", function() {
gauge.labels({ a: '1', b: '2'});
gauge.labels({ a: "1", b: "2"});
assert(gauge._values.has('a="1",b="2"'), "value was not set");
gauge.labels('4', '5');
gauge.labels("4", "5");
assert(gauge._values.has('a="4",b="5"'), "value was not set");
});
it("should return a child supporting the usual methods", function() {
let child = gauge.labels({ a: '1', b: '2'});
let child = gauge.labels({ a: "1", b: "2"});
child.get();
child.inc();
child.dec();
child.setToCurrentTime();
child = gauge.labels('7', '8');
child = gauge.labels("7", "8");
child.get();
child.inc();
child.dec();
child.setToCurrentTime();
});
it("should return the same child for the same labels", function() {
let child = gauge.labels('1', '2');
assert.equal(gauge.labels('1', '2'), child);
let child = gauge.labels("1", "2");
assert.equal(gauge.labels("1", "2"), child);
});
});
describe(".remove()", function() {
it("should remove a label set created with .labels()", function() {
let gauge = new prometheus.Gauge(
'test', "Help", { register: false, labels: ['a', 'b'] }
"test", "Help", { register: false, labels: ["a", "b"] }
);
gauge.labels({ a: '1', b: '2'});
gauge.remove({ a: '1', b: '2'});
gauge.labels({ a: "1", b: "2"});
gauge.remove({ a: "1", b: "2"});
assert(!gauge._values.has('a="1",b="2"'), "value was not removed");
});
it("should throw when removing the empty label set", function() {
let gauge = new prometheus.Gauge('test', "Help", { register: false });
let gauge = new prometheus.Gauge("test", "Help", { register: false });
assert.throws(
() => gauge.remove({}), new Error("labels cannot be empty")
);
@@ -330,12 +330,12 @@ describe("lib/prometheus", function() {
describe(".removeAll()", function() {
it("should remove a label set created with .labels()", function() {
let gauge = new prometheus.Gauge(
'test', "Help", { register: false, labels: ['a', 'b'] }
"test", "Help", { register: false, labels: ["a", "b"] }
);
gauge.labels('1', '2');
gauge.labels('1', '3');
gauge.labels('4', '6');
gauge.removeAll({a: '1'});
gauge.labels("1", "2");
gauge.labels("1", "3");
gauge.labels("4", "6");
gauge.removeAll({a: "1"});
assert(gauge._values.size <= 1, "Matching labels remained")
assert(
gauge._values.has('a="4",b="6"'),
@@ -343,16 +343,16 @@ describe("lib/prometheus", function() {
);
});
it("should throw when removing the empty label set", function() {
let gauge = new prometheus.Gauge('test', "Help", { register: false });
let gauge = new prometheus.Gauge("test", "Help", { register: false });
assert.throws(
() => gauge.removeAll({}), new Error("labels cannot be empty")
);
});
it("should handle special characters", function() {
let gauge = new prometheus.Gauge(
'test', "Help", { register: false, labels: ['a', 'b'] }
"test", "Help", { register: false, labels: ["a", "b"] }
)
gauge.labels('x\\\\\n\"\"\n\\', '2');
gauge.labels('x\\\\\n\"\"\n\\', "2");
gauge.removeAll({a: 'x\\\\\n\"\"\n\\'});
assert(gauge._values.size === 0, "Matching labels remained")
});
@@ -360,16 +360,16 @@ describe("lib/prometheus", function() {
describe(".clear()", function() {
it("should remove all label sets created with .labels()", function() {
let gauge = new prometheus.Gauge(
'test', "Help", { register: false, labels: ['a', 'b'] }
"test", "Help", { register: false, labels: ["a", "b"] }
);
gauge.labels({ a: '1', b: '2'});
gauge.labels({ a: '3', b: '4'});
gauge.labels({ a: '5', b: '6'});
gauge.labels({ a: "1", b: "2"});
gauge.labels({ a: "3", b: "4"});
gauge.labels({ a: "5", b: "6"});
gauge.clear();
assert(gauge._values.size == 0, "values was not cleared");
});
it("should throw when used on an unlabled metric", function() {
let gauge = new prometheus.Gauge('test', "Help", { register: false });
let gauge = new prometheus.Gauge("test", "Help", { register: false });
assert.throws(
() => gauge.clear(), new Error("Cannot clear unlabeled metric")
);
@@ -393,7 +393,7 @@ describe("lib/prometheus", function() {
);
assert(
Math.abs(results[0].samples.get('') - Date.now() / 1000) < 1,
Math.abs(results[0].samples.get("") - Date.now() / 1000) < 1,
"value set is not close to the current unix time"
);
});
@@ -412,7 +412,7 @@ describe("lib/prometheus", function() {
"collector did not give exactly one result"
);
let value = results[0].samples.get('')
let value = results[0].samples.get("")
assert(
value < 5 && value > 0,
`process time is not between 0 and 5 seconds (${value})`
@@ -433,7 +433,7 @@ describe("lib/prometheus", function() {
"collector did not give exactly one result"
);
let value = results[0].samples.get('')
let value = results[0].samples.get("")
assert(
value < 200e6 && value > 0,
`resident memory is not between 0 and 200 MB (${value})`
@@ -454,7 +454,7 @@ describe("lib/prometheus", function() {
"collector did not give exactly one result"
);
let value = results[0].samples.get('')
let value = results[0].samples.get("")
assert(
value < 200e6 && value > 0,
`heap is not between 0 and 200 MB (${value})`
@@ -466,35 +466,35 @@ describe("lib/prometheus", function() {
describe("exposition()", function() {
it("should format simple metrics", async function() {
let registry = new prometheus.CollectorRegistry();
let counter = new prometheus.Counter('a', "Help", { register: false });
let counter = new prometheus.Counter("a", "Help", { register: false });
registry.register(counter);
let gauge = new prometheus.Gauge('b', "Help", { register: false });
let gauge = new prometheus.Gauge("b", "Help", { register: false });
registry.register(gauge);
let exposition = await prometheus.exposition(registry.collect());
assert.equal(
exposition,
'# HELP a Help\n' +
'# TYPE a counter\n' +
'a 0\n' +
'\n' +
'# HELP b Help\n' +
'# TYPE b gauge\n' +
'b 0\n'
"# HELP a Help\n" +
"# TYPE a counter\n" +
"a 0\n" +
"\n" +
"# HELP b Help\n" +
"# TYPE b gauge\n" +
"b 0\n"
);
});
it("should format labeled metrics", async function() {
let registry = new prometheus.CollectorRegistry();
let gauge = new prometheus.Gauge(
'test', "Help", { register: false, labels: ['a', 'b']}
"test", "Help", { register: false, labels: ["a", "b"]}
);
gauge.labels({a: '1', b: '2'});
gauge.labels({b: 'y', a: 'x'});
gauge.labels({a: "1", b: "2"});
gauge.labels({b: "y", a: "x"});
registry.register(gauge);
let exposition = await prometheus.exposition(registry.collect());
assert.equal(
exposition,
'# HELP test Help\n' +
'# TYPE test gauge\n' +
"# HELP test Help\n" +
"# TYPE test gauge\n" +
'test{a="1",b="2"} 0\n' +
'test{a="x",b="y"} 0\n'
);
@@ -502,17 +502,17 @@ describe("lib/prometheus", function() {
it("should format Infinity and NaN", async function() {
let registry = new prometheus.CollectorRegistry();
let gauge = new prometheus.Gauge(
'test', "Help", { register: false, labels: ['n']}
"test", "Help", { register: false, labels: ["n"]}
);
gauge.labels({n: '1'}).set(Infinity);
gauge.labels({n: '2'}).set(-Infinity);
gauge.labels({n: '3'}).set(NaN);
gauge.labels({n: "1"}).set(Infinity);
gauge.labels({n: "2"}).set(-Infinity);
gauge.labels({n: "3"}).set(NaN);
registry.register(gauge);
let exposition = await prometheus.exposition(registry.collect());
assert.equal(
exposition,
'# HELP test Help\n' +
'# TYPE test gauge\n' +
"# HELP test Help\n" +
"# TYPE test gauge\n" +
'test{n="1"} +Inf\n' +
'test{n="2"} -Inf\n' +
'test{n="3"} NaN\n'
@@ -521,11 +521,11 @@ describe("lib/prometheus", function() {
});
let serializedResult = {
metric: { type: 'type', name: 'name', help: "Help", labels: ['a', 'b'] },
metric: { type: "type", name: "name", help: "Help", labels: ["a", "b"] },
samples: [ ['a="1",b="2"', 1], ['a="3",b="4"', 5], ]
};
let deserializedResult = {
metric: new prometheus.Metric('type', 'name', "Help", ['a', 'b']),
metric: new prometheus.Metric("type", "name", "Help", ["a", "b"]),
samples: new Map([['a="1",b="2"', 1], ['a="3",b="4"', 5]]),
};
describe("serializeResult()", function() {
@@ -538,21 +538,21 @@ describe("lib/prometheus", function() {
it("should support adding labels", function() {
assert.deepEqual(
prometheus.serializeResult({
metric: new prometheus.Metric('type', 'name', "Help"),
samples: new Map([['', 2]]),
}, { addLabels: { c: '8' }}),
metric: new prometheus.Metric("type", "name", "Help"),
samples: new Map([["", 2]]),
}, { addLabels: { c: "8" }}),
{
metric: {type: 'type', name: 'name', help: "Help", labels: ['c']},
metric: {type: "type", name: "name", help: "Help", labels: ["c"]},
samples: [['c="8"', 2]],
}
);
assert.deepEqual(
prometheus.serializeResult({
metric: new prometheus.Metric('type', 'name', "Help", ['a']),
metric: new prometheus.Metric("type", "name", "Help", ["a"]),
samples: new Map([['a="4"', 3]]),
}, { addLabels: { c: '8' }}),
}, { addLabels: { c: "8" }}),
{
metric: {type: 'type', name: 'name', help: "Help", labels: ['a', 'c']},
metric: {type: "type", name: "name", help: "Help", labels: ["a", "c"]},
samples: [['a="4",c="8"', 3]],
}
);
@@ -560,30 +560,30 @@ describe("lib/prometheus", function() {
it("should support redefining name and help", function() {
assert.deepEqual(
prometheus.serializeResult({
metric: new prometheus.Metric('type', 'name', "Help"),
samples: new Map([['', 2]]),
}, { metricName: 'new', }),
metric: new prometheus.Metric("type", "name", "Help"),
samples: new Map([["", 2]]),
}, { metricName: "new", }),
{
metric: {type: 'type', name: 'new', help: "Help", labels: []},
samples: [['', 2]],
metric: {type: "type", name: "new", help: "Help", labels: []},
samples: [["", 2]],
}
);
assert.deepEqual(
prometheus.serializeResult({
metric: new prometheus.Metric('type', 'name', "Help"),
samples: new Map([['', 2]]),
metric: new prometheus.Metric("type", "name", "Help"),
samples: new Map([["", 2]]),
}, { metricHelp: "old", }),
{
metric: {type: 'type', name: 'name', help: "old", labels: []},
samples: [['', 2]],
metric: {type: "type", name: "name", help: "old", labels: []},
samples: [["", 2]],
}
);
});
it("should throw on unrecoginzed option", function() {
assert.throws(
() => new prometheus.serializeResult({
metric: new prometheus.Metric('type', 'name', "Help"),
samples: new Map([['', 3]]),
metric: new prometheus.Metric("type", "name", "Help"),
samples: new Map([["", 3]]),
}, { invalid: true }),
new Error("Unrecognized option 'invalid'")
);
+4 -4
View File
@@ -1,8 +1,8 @@
const assert = require('assert').strict;
const assert = require("assert").strict;
const mock = require('./mock');
const master = require('../master');
const mock = require("./mock");
const master = require("../master");
describe('Master testing', function() {
describe("Master testing", function() {
});
+2 -2
View File
@@ -1,5 +1,5 @@
// These are libraries that does not have any units test, they are
// required here in order to track coverage for them.
require('lib/manager/modManager');
require('lib/npmPostinstall.js');
require("lib/manager/modManager");
require("lib/npmPostinstall.js");
+4 -4
View File
@@ -42,7 +42,7 @@ class MockConnector extends events.EventEmitter {
send(type, data) {
let message = { seq: this._seq, type, data };
this.sentMessages.push(message);
setImmediate(() => this.emit('send', message));
setImmediate(() => this.emit("send", message));
return this._seq++;
}
}
@@ -55,13 +55,13 @@ class MockServer {
async sendRcon(command) {
this.rconCommands.push(command);
return this.rconCommandResults.get(command) || '';
return this.rconCommandResults.get(command) || "";
}
}
class MockInstance extends link.Link {
constructor() {
super('instance', 'slave', new MockConnector());
super("instance", "slave", new MockConnector());
this.server = new MockServer();
this.name = "test";
this.config = {
@@ -75,7 +75,7 @@ class MockInstance extends link.Link {
class MockSlave extends link.Link {
constructor() {
super('slave', 'master', new MockConnector());
super("slave", "master", new MockConnector());
}
}
+9 -9
View File
@@ -1,6 +1,6 @@
const assert = require('assert').strict;
const path = require('path');
const fs = require('fs-extra');
const assert = require("assert").strict;
const path = require("path");
const fs = require("fs-extra");
const link = require("lib/link");
const config = require("lib/config");
@@ -65,19 +65,19 @@ describe("Slave testing", function() {
});
it("should throw on CON, PRN, AUX, NUL, COM1, LPT1", function() {
for (let bad of ['CON', 'PRN', 'AUX', 'NUL', 'COM1', 'LPT1']) {
for (let bad of ["CON", "PRN", "AUX", "NUL", "COM1", "LPT1"]) {
check(
bad, 'cannot be named any of . ..'
+' CON PRN AUX NUL COM1-9 and LPT1-9'
bad, "cannot be named any of . .."
+" CON PRN AUX NUL COM1-9 and LPT1-9"
);
}
});
it("should throw on . and ..", function() {
for (let bad of ['.', '..']) {
for (let bad of [".", ".."]) {
check(
bad, 'cannot be named any of . ..'
+' CON PRN AUX NUL COM1-9 and LPT1-9'
bad, "cannot be named any of . .."
+" CON PRN AUX NUL COM1-9 and LPT1-9"
);
}
});