mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-14 23:24:52 +09:00
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:
1 parent
efd759bec5
commit
34aaeee354
48 files changed
+708
-712
No files matched your search
+7
-7
@@ -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
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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()))
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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",
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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");
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,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();
|
||||
});
|
||||
@@ -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");
|
||||
@@ -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
@@ -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" }],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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");
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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")();
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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"
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user