mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-15 23:24:52 +09:00
Merge branch 'master' into feature/plugin-install
This commit is contained in:
277 files changed
+2557
-2079
No files matched your search
+4
-10
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const { compile } = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import { compile } from "@clusterio/lib";
|
||||
|
||||
/**
|
||||
* Generate a flat array of tests from a matrix of inputs.
|
||||
@@ -10,7 +9,7 @@ const { compile } = require("@clusterio/lib");
|
||||
* @returns {Array<{ [K in keyof T]: T[K][number] }>}
|
||||
* An array of tuples, each containing one value from each input array.
|
||||
*/
|
||||
function testMatrix(...arrays) {
|
||||
export function testMatrix(...arrays) {
|
||||
return arrays.reduce((acc, curr) => acc.flatMap(a => curr.map(b => [...a, b])), [[]]);
|
||||
}
|
||||
|
||||
@@ -21,7 +20,7 @@ function testMatrix(...arrays) {
|
||||
* @param {{new(...args: T): object}} Class - The class which has toJSON and fromJSON methods.
|
||||
* @param {T[]} tests - The tests inputs to pass to the class constructor.
|
||||
*/
|
||||
function testRoundTripJsonSerialisable(Class, tests) {
|
||||
export function testRoundTripJsonSerialisable(Class, tests) {
|
||||
const validate = compile(Class.jsonSchema);
|
||||
for (const test of tests) {
|
||||
const original = new Class(...test);
|
||||
@@ -34,8 +33,3 @@ function testRoundTripJsonSerialisable(Class, tests) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
testMatrix,
|
||||
testRoundTripJsonSerialisable,
|
||||
};
|
||||
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
const mock = require("../mock");
|
||||
const controller = require("@clusterio/controller");
|
||||
import * as mock from "../mock.js";
|
||||
import * as controller from "@clusterio/controller";
|
||||
|
||||
describe("controller/src/BaseControllerPlugin", function() {
|
||||
describe("class BaseControllerPlugin", function() {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const { ControlConnection } = require("@clusterio/controller");
|
||||
import assert from "node:assert/strict";
|
||||
import { ControlConnection } from "@clusterio/controller";
|
||||
|
||||
describe("controller/src/ControlConnection", function() {
|
||||
describe(".handleControllerRestartRequest()", function() {
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
"use strict";
|
||||
const path = require("node:path");
|
||||
const assert = require("assert").strict;
|
||||
const { Controller, HostRecord, InstanceRecord, UserRecord } = require("@clusterio/controller");
|
||||
const { EventEmitter } = require("stream");
|
||||
const events = require("node:events");
|
||||
const http = require("node:http");
|
||||
const express = require("express");
|
||||
import path from "node:path";
|
||||
import assert from "node:assert/strict";
|
||||
import { Controller, HostRecord, InstanceRecord, UserRecord } from "@clusterio/controller";
|
||||
import events, { EventEmitter } from "node:events";
|
||||
import http from "node:http";
|
||||
import express from "express";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const {
|
||||
import {
|
||||
ControllerConfig, Address, RequestError,
|
||||
InstanceConfig, SystemInfo, Role, ModPack,
|
||||
} = require("@clusterio/lib");
|
||||
addPluginConfigFields,
|
||||
} from "@clusterio/lib";
|
||||
|
||||
class MockEvent {}
|
||||
|
||||
@@ -32,10 +32,12 @@ class MockInstanceConfig extends EventEmitter {
|
||||
}
|
||||
|
||||
describe("controller/src/Controller", function() {
|
||||
describe("class Controller", function() {
|
||||
describe("class Controller", async function() {
|
||||
/** @type {Controller} */
|
||||
let controller, mockInstanceConfig;
|
||||
const controllerVersion = require("@clusterio/controller/package.json").version;
|
||||
const controllerVersion = (
|
||||
await import("@clusterio/controller/package.json", { with: { type: "json" }})
|
||||
).default.version;
|
||||
before(async function() {
|
||||
const controllerConfig = new ControllerConfig("controller", { "controller.version": controllerVersion });
|
||||
controller = new Controller({}, [], controllerConfig);
|
||||
@@ -234,14 +236,17 @@ describe("controller/src/Controller", function() {
|
||||
});
|
||||
});
|
||||
describe(".checkRestartRequired()", function() {
|
||||
before(function() {
|
||||
addPluginConfigFields([{ name: "restart_test" }]);
|
||||
});
|
||||
beforeEach(function() {
|
||||
// Would not be needed if controller setup was beforeEach
|
||||
controller.config.restartRequired = false;
|
||||
controller.config.set("controller.version", controllerVersion);
|
||||
controller.config.set("global_chat.load_plugin", true);
|
||||
controller.config.set("restart_test.load_plugin", true);
|
||||
controller.config.restartRequired = false;
|
||||
controller.pluginInfos[0] = {
|
||||
name: "global_chat",
|
||||
requirePath: path.dirname(require.resolve("@clusterio/controller/package.json")),
|
||||
name: "restart_test",
|
||||
packagePath: fileURLToPath(import.meta.resolve("@clusterio/controller/package.json")),
|
||||
version: controllerVersion,
|
||||
};
|
||||
});
|
||||
@@ -256,7 +261,7 @@ describe("controller/src/Controller", function() {
|
||||
controller.pluginInfos[0].version = "0.0.0";
|
||||
controller.pluginInfos[0].webEntrypoint = true;
|
||||
controller.pluginInfos[0].controllerEntrypoint = true;
|
||||
controller.config.set("global_chat.load_plugin", false);
|
||||
controller.config.set("restart_test.load_plugin", false);
|
||||
controller.config.restartRequired = false; // Setting load_plugin requires a restart
|
||||
const result = await controller.checkRestartRequired();
|
||||
assert.equal(result, false);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
const { User } = require("@clusterio/controller");
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { User } from "@clusterio/controller";
|
||||
|
||||
describe("controller/src/User", function() {
|
||||
describe("class User", function() {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const { HostDetails } = require("@clusterio/lib");
|
||||
const { HostRecord } = require("@clusterio/controller");
|
||||
import assert from "node:assert/strict";
|
||||
import { HostDetails } from "@clusterio/lib";
|
||||
import { HostRecord } from "@clusterio/controller";
|
||||
|
||||
const { testMatrix, testRoundTripJsonSerialisable } = require("../common");
|
||||
import { testMatrix, testRoundTripJsonSerialisable } from "../common.js";
|
||||
|
||||
describe("controller/HostRecord", function () {
|
||||
const samplePlugins = new Map([
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const http = require("http");
|
||||
const https = require("https");
|
||||
const util = require("util");
|
||||
const events = require("node:events");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import http from "node:http";
|
||||
import https from "node:https";
|
||||
import util from "node:util";
|
||||
import events from "node:events";
|
||||
|
||||
const HttpCloser = require("@clusterio/controller/dist/node/src/HttpCloser").default;
|
||||
import HttpCloser from "@clusterio/controller/dist/node/src/HttpCloser.js";
|
||||
|
||||
// Time to wait during async operations to ensure they happened in order.
|
||||
const tick = 20;
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
const { Controller, InstanceRecord, InstanceManager } = require("@clusterio/controller");
|
||||
import { Controller, InstanceRecord, InstanceManager } from "@clusterio/controller";
|
||||
|
||||
describe("controller/InstanceManager", function () {
|
||||
/** @type {Controller} */
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
const { InstanceRecord } = require("@clusterio/controller");
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { InstanceRecord } from "@clusterio/controller";
|
||||
|
||||
const { testMatrix, testRoundTripJsonSerialisable } = require("../common");
|
||||
import { testMatrix, testRoundTripJsonSerialisable } from "../common.js";
|
||||
|
||||
describe("controller/InstanceRecord", function () {
|
||||
/** @type {lib.InstanceConfig} */
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const { Role, SubscribableDatastore } = require("@clusterio/lib");
|
||||
const { User } = require("@clusterio/controller");
|
||||
import assert from "node:assert/strict";
|
||||
import { Role, SubscribableDatastore } from "@clusterio/lib";
|
||||
import { User } from "@clusterio/controller";
|
||||
|
||||
describe("controller/User", function () {
|
||||
/** @type {SubscribableDatastore<UserRecord>} */
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
"use strict";
|
||||
const path = require("path");
|
||||
const fs = require("node:fs/promises");
|
||||
const assert = require("assert").strict;
|
||||
const jwt = require("jsonwebtoken");
|
||||
const { Role, SubscribableDatastore, ControllerConfig } = require("@clusterio/lib");
|
||||
const { UserRecord, UserManager } = require("@clusterio/controller");
|
||||
import path from "node:path";
|
||||
import fs from "node:fs/promises";
|
||||
import assert from "node:assert/strict";
|
||||
import jwt from "jsonwebtoken";
|
||||
import { Role, SubscribableDatastore, ControllerConfig } from "@clusterio/lib";
|
||||
import { UserRecord, UserManager } from "@clusterio/controller";
|
||||
|
||||
const TEMP_DIR = path.join("temp", "test", "UserManager");
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const { UserDetails, PlayerStats } = require("@clusterio/lib");
|
||||
const { UserRecord } = require("@clusterio/controller");
|
||||
import assert from "node:assert/strict";
|
||||
import { UserDetails, PlayerStats } from "@clusterio/lib";
|
||||
import { UserRecord } from "@clusterio/controller";
|
||||
|
||||
const { testMatrix, testRoundTripJsonSerialisable } = require("../common");
|
||||
import { testMatrix, testRoundTripJsonSerialisable } from "../common.js";
|
||||
|
||||
describe("controller/UserRecord", function () {
|
||||
it("should be round trip serialisable", function () {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const { Controller, WsServer } = require("@clusterio/controller");
|
||||
const { ControllerConfig } = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import { Controller, WsServer } from "@clusterio/controller";
|
||||
import { ControllerConfig } from "@clusterio/lib";
|
||||
|
||||
describe("controller/src/WsServer", function() {
|
||||
describe("class WsServer", function() {
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const events = require("events");
|
||||
const FormData = require("form-data");
|
||||
const http = require("http");
|
||||
import assert from "node:assert/strict";
|
||||
import events from "node:events";
|
||||
import FormData from "form-data";
|
||||
import http from "node:http";
|
||||
|
||||
const { wait } = require("@clusterio/lib");
|
||||
const routes = require("@clusterio/controller/dist/node/src/routes");
|
||||
const mock = require("../mock");
|
||||
import { wait } from "@clusterio/lib";
|
||||
import * as routes from "@clusterio/controller/dist/node/src/routes.js";
|
||||
import * as mock from "../mock.js";
|
||||
|
||||
describe("controller/src/routes", function() {
|
||||
let controller;
|
||||
@@ -103,7 +102,7 @@ describe("controller/src/routes", function() {
|
||||
});
|
||||
it("should report missing manifest and entrypoint", async function() {
|
||||
controller.pluginInfos = [
|
||||
{ name: "foo", version: "1.0.0", npmPackage: "foo" },
|
||||
{ name: "foo", version: "1.0.0", npmPackage: "foo", webEntrypoint: "dist/web/index.js" },
|
||||
{ name: "bar", version: "1.0.0", npmPackage: "bar", manifest: {} },
|
||||
{ name: "baz", version: "1.0.0", npmPackage: "baz", manifest: { "baz.js": "remoteEntry.js" } },
|
||||
];
|
||||
@@ -116,6 +115,19 @@ describe("controller/src/routes", function() {
|
||||
assert.equal(data[1].loaded, false);
|
||||
assert.equal(data[1].enabled, false);
|
||||
});
|
||||
it("should not report a missing manifest for plugins without a web build", async function() {
|
||||
controller.pluginInfos = [
|
||||
{ name: "foo", version: "1.0.0", npmPackage: "foo", hostEntrypoint: "dist/node/host.js" },
|
||||
{ name: "bar", version: "1.0.0", npmPackage: "bar", controllerEntrypoint: "dist/node/controller.js" },
|
||||
{ name: "baz", version: "1.0.0", npmPackage: "baz", instanceConfigFields: {} },
|
||||
];
|
||||
let response = await fetch(endpoint);
|
||||
assert.equal(response.status, 200);
|
||||
let data = await response.json();
|
||||
assert.deepEqual(data[0].web, {});
|
||||
assert.equal(data[1].web.error, "Missing dist/web/manifest.json");
|
||||
assert.equal(data[2].web.error, "Missing dist/web/manifest.json");
|
||||
});
|
||||
});
|
||||
describe("/api/cluster-name", function() {
|
||||
let endpoint;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
"use strict";
|
||||
if (module === require.main) {
|
||||
if (import.meta.main) {
|
||||
process.stdout.write(JSON.stringify(process.argv.slice(2)));
|
||||
}
|
||||
@@ -1,17 +1,16 @@
|
||||
"use strict";
|
||||
const child_process = require("child_process");
|
||||
const util = require("util");
|
||||
const assert = require("assert").strict;
|
||||
const path = require("path");
|
||||
import child_process from "node:child_process";
|
||||
import util from "node:util";
|
||||
import assert from "node:assert/strict";
|
||||
import path from "node:path";
|
||||
|
||||
const { escapeArg } = require("../../packages/create/escape_arg");
|
||||
import { escapeArg } from "../../packages/create/escape_arg.js";
|
||||
const execFile = util.promisify(child_process.execFile);
|
||||
|
||||
async function exec(file, args) {
|
||||
const command = [file, ...args.map(escapeArg)].join(" ");
|
||||
const { stdout, stderr } = await execFile(
|
||||
command,
|
||||
{ shell: true, cwd: __dirname, env: { ...process.env, pct: "%"} }
|
||||
{ shell: true, cwd: import.meta.dirname, env: { ...process.env, pct: "%"} }
|
||||
);
|
||||
return { stdout: JSON.parse(stdout), stderr };
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
const { Command, CommandTree } = require("@clusterio/lib");
|
||||
const { BaseCtlPlugin } = require("@clusterio/ctl");
|
||||
import { Command, CommandTree } from "@clusterio/lib";
|
||||
import { BaseCtlPlugin } from "@clusterio/ctl";
|
||||
|
||||
const testPluginCommands = new CommandTree({
|
||||
name: "test-plugin", description: "Test plugin commands",
|
||||
@@ -15,12 +14,8 @@ testPluginCommands.add(new Command({
|
||||
},
|
||||
}));
|
||||
|
||||
class CtlPlugin extends BaseCtlPlugin {
|
||||
export class CtlPlugin extends BaseCtlPlugin {
|
||||
async addCommands(rootCommand) {
|
||||
rootCommand.add(testPluginCommands);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
CtlPlugin,
|
||||
};
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const { BaseControllerPlugin } = require("@clusterio/controller");
|
||||
import { BaseControllerPlugin } from "@clusterio/controller";
|
||||
|
||||
const { ControllerEcho, HostEcho } = require("./messages");
|
||||
import { ControllerEcho, HostEcho } from "./messages.js";
|
||||
|
||||
class ControllerPlugin extends BaseControllerPlugin {
|
||||
export class ControllerPlugin extends BaseControllerPlugin {
|
||||
async init() {
|
||||
this.logger.info("test_plugin controller loaded");
|
||||
this.controller.handle(ControllerEcho, this.handleControllerEcho.bind(this));
|
||||
@@ -15,7 +14,3 @@ class ControllerPlugin extends BaseControllerPlugin {
|
||||
return request.text;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
ControllerPlugin,
|
||||
};
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const { BaseHostPlugin } = require("@clusterio/host");
|
||||
import { BaseHostPlugin } from "@clusterio/host";
|
||||
|
||||
const { HostEcho, HostEchoReceived } = require("./messages");
|
||||
import { HostEcho, HostEchoReceived } from "./messages.js";
|
||||
|
||||
class HostPlugin extends BaseHostPlugin {
|
||||
export class HostPlugin extends BaseHostPlugin {
|
||||
async init() {
|
||||
this.logger.info("test_plugin host loaded");
|
||||
this.receivedEchoes = new Set();
|
||||
@@ -20,7 +19,3 @@ class HostPlugin extends BaseHostPlugin {
|
||||
return this.receivedEchoes.has(request.text);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
HostPlugin,
|
||||
};
|
||||
@@ -1,24 +1,21 @@
|
||||
"use strict";
|
||||
// Plugin exercising the plugin system in the integration tests, see #342.
|
||||
// Written as plain JavaScript so that it does not need to be built.
|
||||
|
||||
const { ControllerEcho, HostEcho, HostEchoReceived } = require("./messages");
|
||||
import { ControllerEcho, HostEcho, HostEchoReceived } from "./messages.js";
|
||||
|
||||
module.exports = {
|
||||
plugin: {
|
||||
name: "test_plugin",
|
||||
title: "Test Plugin",
|
||||
description: "Plugin used to test the plugin system.",
|
||||
export const plugin = {
|
||||
name: "test_plugin",
|
||||
title: "Test Plugin",
|
||||
description: "Plugin used to test the plugin system.",
|
||||
|
||||
controllerEntrypoint: "controller",
|
||||
hostEntrypoint: "host",
|
||||
instanceEntrypoint: "instance",
|
||||
ctlEntrypoint: "control",
|
||||
controllerEntrypoint: "controller.js",
|
||||
hostEntrypoint: "host.js",
|
||||
instanceEntrypoint: "instance.js",
|
||||
ctlEntrypoint: "control.js",
|
||||
|
||||
messages: [
|
||||
ControllerEcho,
|
||||
HostEcho,
|
||||
HostEchoReceived,
|
||||
],
|
||||
},
|
||||
messages: [
|
||||
ControllerEcho,
|
||||
HostEcho,
|
||||
HostEchoReceived,
|
||||
],
|
||||
};
|
||||
@@ -1,12 +1,7 @@
|
||||
"use strict";
|
||||
const { BaseInstancePlugin } = require("@clusterio/host");
|
||||
import { BaseInstancePlugin } from "@clusterio/host";
|
||||
|
||||
class InstancePlugin extends BaseInstancePlugin {
|
||||
export class InstancePlugin extends BaseInstancePlugin {
|
||||
async init() {
|
||||
this.logger.info("test_plugin instance loaded");
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
InstancePlugin,
|
||||
};
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const { JsonBoolean, JsonString } = require("@clusterio/lib");
|
||||
import { JsonBoolean, JsonString } from "@clusterio/lib";
|
||||
|
||||
// Sent from ctl to the controller, which answers with the text it was given
|
||||
// and broadcasts a HostEcho to the hosts.
|
||||
class ControllerEcho {
|
||||
export class ControllerEcho {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "controller";
|
||||
@@ -21,7 +20,7 @@ class ControllerEcho {
|
||||
}
|
||||
|
||||
// Broadcast from the controller to the hosts by broadcastEventToHosts.
|
||||
class HostEcho {
|
||||
export class HostEcho {
|
||||
static type = "event";
|
||||
static src = "controller";
|
||||
static dst = "host";
|
||||
@@ -39,7 +38,7 @@ class HostEcho {
|
||||
|
||||
// Sent from ctl to a host, which answers with whether it received the given
|
||||
// text via a HostEcho.
|
||||
class HostEchoReceived {
|
||||
export class HostEchoReceived {
|
||||
static type = "request";
|
||||
static src = "control";
|
||||
static dst = "host";
|
||||
@@ -55,9 +54,3 @@ class HostEchoReceived {
|
||||
toJSON() { return this.text; }
|
||||
static fromJSON(json) { return new this(json); }
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
ControllerEcho,
|
||||
HostEcho,
|
||||
HostEchoReceived,
|
||||
};
|
||||
@@ -3,6 +3,7 @@
|
||||
"version": "0.0.1",
|
||||
"description": "Plugin used to test the plugin system, see #342",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"clusterio-plugin"
|
||||
|
||||
+21
-15
@@ -1,12 +1,11 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const Host = require("@clusterio/host/dist/node/src/Host").default;
|
||||
const Instance = require("@clusterio/host/dist/node/src/Instance").default;
|
||||
const { _discoverInstances } = require("@clusterio/host/dist/node/src/Host");
|
||||
const { HostConnector } = require("@clusterio/host/dist/node/host");
|
||||
import * as lib from "@clusterio/lib";
|
||||
import Host, { _discoverInstances } from "@clusterio/host/dist/node/src/Host.js";
|
||||
import Instance from "@clusterio/host/dist/node/src/Instance.js";
|
||||
import { HostConnector } from "@clusterio/host/dist/node/host.js";
|
||||
|
||||
describe("Host testing", function() {
|
||||
describe("discoverInstances()", function() {
|
||||
@@ -116,14 +115,19 @@ describe("Host testing", function() {
|
||||
]);
|
||||
});
|
||||
});
|
||||
describe(".checkRestartRequired()", function() {
|
||||
describe(".checkRestartRequired()", async function() {
|
||||
let host;
|
||||
const hostVersion = require("@clusterio/host/package.json").version;
|
||||
const hostVersion = (
|
||||
await import("@clusterio/host/package.json", { with: { type: "json" }})
|
||||
).default.version;
|
||||
before(function() {
|
||||
lib.addPluginConfigFields([{ name: "restart_test", hostEntrypoint: "host.js" }]);
|
||||
});
|
||||
beforeEach(function() {
|
||||
// This can be used more generally, but i did not want to interfere with handleSyncUserListsEvent
|
||||
const pluginInfos = [{
|
||||
name: "global_chat",
|
||||
requirePath: path.dirname(require.resolve("@clusterio/host/package.json")),
|
||||
name: "restart_test",
|
||||
packagePath: fileURLToPath(import.meta.resolve("@clusterio/host/package.json")),
|
||||
version: hostVersion,
|
||||
}];
|
||||
const hostConfig = new lib.HostConfig("host", { "host.version": hostVersion });
|
||||
@@ -141,7 +145,7 @@ describe("Host testing", function() {
|
||||
host.pluginInfos[0].version = "0.0.0";
|
||||
host.pluginInfos[0].hostEntrypoint = true;
|
||||
host.pluginInfos[0].instanceEntrypoint = true;
|
||||
host.config.set("global_chat.load_plugin", false);
|
||||
host.config.set("restart_test.load_plugin", false);
|
||||
host.config.restartRequired = false; // Setting load_plugin requires a restart
|
||||
const result = await host.checkRestartRequired();
|
||||
assert.equal(result, false);
|
||||
@@ -174,9 +178,11 @@ describe("Host testing", function() {
|
||||
assert.equal(host.config.restartRequired, true);
|
||||
});
|
||||
});
|
||||
describe(".checkRestartDowngrade()", function() {
|
||||
describe(".checkRestartDowngrade()", async function() {
|
||||
let host;
|
||||
const hostVersion = require("@clusterio/host/package.json").version;
|
||||
const hostVersion = (
|
||||
await import("@clusterio/host/package.json", { with: { type: "json" }})
|
||||
).default.version;
|
||||
beforeEach(function() {
|
||||
const hostConfig = new lib.HostConfig("host", { "host.version": hostVersion });
|
||||
const hostConnector = new HostConnector(hostConfig, []);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const mock = require("../mock");
|
||||
import * as mock from "../mock.js";
|
||||
|
||||
const host = require("@clusterio/host");
|
||||
import * as host from "@clusterio/host";
|
||||
|
||||
describe("host/src/BaseHostPlugin", function() {
|
||||
describe("class BaseHostPlugin", function() {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const mock = require("../mock");
|
||||
import assert from "node:assert/strict";
|
||||
import * as mock from "../mock.js";
|
||||
|
||||
const host = require("@clusterio/host");
|
||||
import * as host from "@clusterio/host";
|
||||
|
||||
describe("host/src/BaseInstancePlugin", function() {
|
||||
describe("class BaseInstancePlugin", function() {
|
||||
|
||||
+34
-7
@@ -1,11 +1,10 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import path from "node:path";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { PlayerStats, wait } = lib;
|
||||
const Instance = require("@clusterio/host/dist/node/src/Instance").default;
|
||||
const { MockConnector, MockServer } = require("../mock");
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { PlayerStats, wait } from "@clusterio/lib";
|
||||
import Instance from "@clusterio/host/dist/node/src/Instance.js";
|
||||
import { MockConnector, MockServer } from "../mock.js";
|
||||
|
||||
const addr = lib.Address.fromShorthand;
|
||||
|
||||
@@ -39,6 +38,34 @@ describe("class Instance", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe(".checkModPackVersion()", function() {
|
||||
function modPack(factorioVersion) {
|
||||
return lib.ModPack.fromJSON({ name: "pack", factorio_version: factorioVersion });
|
||||
}
|
||||
|
||||
it("should accept a mod pack for an older or equal Factorio version", function() {
|
||||
instance.server.version = "1.1.91";
|
||||
instance.checkModPackVersion(modPack("1.1"));
|
||||
instance.checkModPackVersion(modPack("1.1.90"));
|
||||
instance.checkModPackVersion(modPack("1.1.91"));
|
||||
});
|
||||
|
||||
it("should reject a mod pack for a newer Factorio version", function() {
|
||||
instance.server.version = "1.1.91";
|
||||
assert.throws(
|
||||
() => instance.checkModPackVersion(modPack("1.1.110")),
|
||||
new lib.RequestError(
|
||||
"Mod pack pack is for Factorio 1.1.110 which is newer than the Factorio 1.1.91 this instance runs"
|
||||
)
|
||||
);
|
||||
assert.throws(() => instance.checkModPackVersion(modPack("2.0")), lib.RequestError);
|
||||
});
|
||||
|
||||
it("should skip the check when the server version is unknown", function() {
|
||||
instance.checkModPackVersion(modPack("2.0"));
|
||||
});
|
||||
});
|
||||
|
||||
describe("._recordPlayerJoin()", function() {
|
||||
it("should add player to playersOnline", function() {
|
||||
instance._recordPlayerJoin("player");
|
||||
|
||||
+4
-5
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import path from "node:path";
|
||||
|
||||
const { FactorioServer } = require("@clusterio/host/dist/node/src/server");
|
||||
const { _exportLocale } = require("@clusterio/host/dist/node/src/export");
|
||||
import { FactorioServer } from "@clusterio/host/dist/node/src/server.js";
|
||||
import { _exportLocale } from "@clusterio/host/dist/node/src/export.js";
|
||||
|
||||
|
||||
describe("host/src/export", function() {
|
||||
|
||||
+6
-7
@@ -1,11 +1,10 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const JSZip = require("jszip");
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import JSZip from "jszip";
|
||||
import path from "node:path";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const patch = require("@clusterio/host/dist/node/src/patch");
|
||||
import * as lib from "@clusterio/lib";
|
||||
import * as patch from "@clusterio/host/dist/node/src/patch.js";
|
||||
|
||||
|
||||
describe("host/patch", function() {
|
||||
|
||||
+9
-11
@@ -1,14 +1,12 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const events = require("events");
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import events from "node:events";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
const hostServer = require("@clusterio/host/dist/node/src/server");
|
||||
const lib = require("@clusterio/lib");
|
||||
const { wait } = lib;
|
||||
const { testLines } = require("../lib/factorio/lines");
|
||||
const { slowTest, externalTest } = require("../integration");
|
||||
import * as hostServer from "@clusterio/host/dist/node/src/server.js";
|
||||
import { Link, wait } from "@clusterio/lib";
|
||||
import { testLines } from "../lib/factorio/lines.js";
|
||||
import { slowTest, externalTest } from "../integration/index.js";
|
||||
|
||||
|
||||
describe("host/server", function() {
|
||||
@@ -326,7 +324,7 @@ describe("host/server", function() {
|
||||
static jsonSchema = { type: "number" };
|
||||
static fromJSON(json) { return new this(json); }
|
||||
}
|
||||
let eventFromJSON = lib.Link.eventFromJSON(NumberEvent, "NumberEvent");
|
||||
let eventFromJSON = Link.eventFromJSON(NumberEvent, "NumberEvent");
|
||||
ipcServer.handle("bad_event", async () => { eventFromJSON("not a number"); });
|
||||
ipcServer.emit("ipc-bad_event", {});
|
||||
await new Promise(resolve => setImmediate(resolve));
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const jwt = require("jsonwebtoken");
|
||||
const path = require("path");
|
||||
const events = require("events");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import jwt from "jsonwebtoken";
|
||||
import path from "node:path";
|
||||
import events from "node:events";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const libBuildMod = require("@clusterio/lib/build_mod");
|
||||
const { wait } = lib;
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { wait } from "@clusterio/lib";
|
||||
import * as libBuildMod from "@clusterio/lib/build_mod.js";
|
||||
|
||||
const testStrings = require("../lib/factorio/test_strings");
|
||||
const {
|
||||
import * as testStrings from "../lib/factorio/test_strings.js";
|
||||
import {
|
||||
TestControl, TestControlConnector, url, controlToken, slowTest,
|
||||
execCtl, execCtlProcess, execController, execHost, sendRcon, getControl,
|
||||
spawnNode, instancesDir, factorioDir, databaseDir, controllerConfigPath,
|
||||
requiresFactorio, hasFactorio,
|
||||
} = require("./index");
|
||||
const { ControllerEcho, HostEchoReceived } = require("../file/test_plugin/messages");
|
||||
} from "./index.js";
|
||||
import { ControllerEcho, HostEchoReceived } from "../file/test_plugin/messages.js";
|
||||
|
||||
|
||||
/** @returns {Promise<Map<number, lib.InstanceDetails>>} */
|
||||
@@ -522,6 +521,9 @@ describe("Integration of Clusterio", function() {
|
||||
it("runs", async function() {
|
||||
await execCtl("controller update");
|
||||
});
|
||||
it("accepts --all", async function() {
|
||||
await execCtl("controller update --all");
|
||||
});
|
||||
it("accepts --restart", async function() {
|
||||
// We cannot restart the controller, so we check for controller error instead
|
||||
await assert.rejects(
|
||||
@@ -604,6 +606,9 @@ describe("Integration of Clusterio", function() {
|
||||
it("runs", async function() {
|
||||
await execCtl("host update 4");
|
||||
});
|
||||
it("accepts --all", async function() {
|
||||
await execCtl("host update 4 --all");
|
||||
});
|
||||
it("accepts --restart", async function() {
|
||||
// We cannot restart the host, so we check for host error instead
|
||||
await assert.rejects(
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const jwt = require("jsonwebtoken");
|
||||
const path = require("path");
|
||||
const events = require("events");
|
||||
const child_process = require("child_process");
|
||||
const util = require("util");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import jwt from "jsonwebtoken";
|
||||
import path from "node:path";
|
||||
import events from "node:events";
|
||||
import child_process from "node:child_process";
|
||||
import util from "node:util";
|
||||
|
||||
const cwd = path.join("temp", "test_integration");
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import path from "node:path";
|
||||
|
||||
const { _exportLocale } = require("@clusterio/host/dist/node/src/export");
|
||||
const { FactorioServer } = require("@clusterio/host/dist/node/src/server");
|
||||
import { _exportLocale } from "@clusterio/host/dist/node/src/export.js";
|
||||
import { FactorioServer } from "@clusterio/host/dist/node/src/server.js";
|
||||
|
||||
const { factorioDir, requiresFactorio } = require("./index");
|
||||
import { factorioDir, requiresFactorio } from "./index.js";
|
||||
|
||||
|
||||
describe("Integration of lib/factorio/export", function() {
|
||||
|
||||
+42
-74
@@ -1,27 +1,26 @@
|
||||
/* eslint-disable no-console */
|
||||
"use strict";
|
||||
const path = require("path");
|
||||
const fs = require("node:fs/promises");
|
||||
const { readFileSync } = require("node:fs");
|
||||
const child_process = require("child_process");
|
||||
const jwt = require("jsonwebtoken");
|
||||
const util = require("util");
|
||||
const events = require("events");
|
||||
import path from "node:path";
|
||||
import fs from "node:fs/promises";
|
||||
import { readFileSync } from "node:fs";
|
||||
import child_process from "node:child_process";
|
||||
import jwt from "jsonwebtoken";
|
||||
import util from "node:util";
|
||||
import events from "node:events";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { LineSplitter, ConsoleTransport, logger } = lib;
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { LineSplitter, ConsoleTransport, logger } from "@clusterio/lib";
|
||||
|
||||
const { selectTargetCommand, initialize: initializeCtl } = require("@clusterio/ctl");
|
||||
const { _listFactorioVersions } = require("@clusterio/host/dist/node/src/server");
|
||||
import { selectTargetCommand, initialize as initializeCtl } from "@clusterio/ctl";
|
||||
import { _listFactorioVersions } from "@clusterio/host/dist/node/src/server.js";
|
||||
|
||||
// Make sure permissions from plugins are loaded
|
||||
require("../../plugins/global_chat/dist/node/index");
|
||||
require("../../plugins/player_auth/dist/node/index");
|
||||
require("../../plugins/research_sync/dist/node/index");
|
||||
require("../../plugins/statistics_exporter/dist/node/index");
|
||||
require("../../plugins/subspace_storage/dist/node/index");
|
||||
import "../../plugins/global_chat/dist/node/index.js";
|
||||
import "../../plugins/player_auth/dist/node/index.js";
|
||||
import "../../plugins/research_sync/dist/node/index.js";
|
||||
import "../../plugins/statistics_exporter/dist/node/index.js";
|
||||
import "../../plugins/subspace_storage/dist/node/index.js";
|
||||
|
||||
class TestControl extends lib.Link {
|
||||
export class TestControl extends lib.Link {
|
||||
constructor(connector, subscribe = true) {
|
||||
super(connector);
|
||||
this.hostUpdates = [];
|
||||
@@ -93,7 +92,7 @@ class TestControl extends lib.Link {
|
||||
}
|
||||
}
|
||||
|
||||
class TestControlConnector extends lib.WebSocketClientConnector {
|
||||
export class TestControlConnector extends lib.WebSocketClientConnector {
|
||||
register() {
|
||||
this.sendHandshake(
|
||||
new lib.MessageRegisterControl(
|
||||
@@ -105,7 +104,7 @@ class TestControlConnector extends lib.WebSocketClientConnector {
|
||||
}
|
||||
}
|
||||
|
||||
class TestHostConnector extends lib.WebSocketClientConnector {
|
||||
export class TestHostConnector extends lib.WebSocketClientConnector {
|
||||
register() {
|
||||
this.sendHandshake(
|
||||
new lib.MessageRegisterHost(
|
||||
@@ -119,7 +118,7 @@ class TestHostConnector extends lib.WebSocketClientConnector {
|
||||
}
|
||||
|
||||
// Mark that this test takes a lot of time, or depends on a test that takes a lot of time.
|
||||
function slowTest(test) {
|
||||
export function slowTest(test) {
|
||||
|
||||
if (process.env.FAST_TEST) {
|
||||
test.skip();
|
||||
@@ -129,7 +128,7 @@ function slowTest(test) {
|
||||
}
|
||||
|
||||
// Mark that this test depends on an external API and may be slow or flaky.
|
||||
function externalTest(test) {
|
||||
export function externalTest(test) {
|
||||
if (process.env.NO_EXTERNAL_TEST) {
|
||||
test.skip();
|
||||
}
|
||||
@@ -138,7 +137,7 @@ function externalTest(test) {
|
||||
}
|
||||
|
||||
// Mark that this test or suite of tests requires a factorio install to run.
|
||||
function requiresFactorio(testOrSuite) {
|
||||
export function requiresFactorio(testOrSuite) {
|
||||
if (testOrSuite.skip) {
|
||||
if (!haveFactorioInstall) {
|
||||
testOrSuite.skip();
|
||||
@@ -152,11 +151,11 @@ function requiresFactorio(testOrSuite) {
|
||||
}
|
||||
}
|
||||
|
||||
function hasFactorio() {
|
||||
export function hasFactorio() {
|
||||
return haveFactorioInstall;
|
||||
}
|
||||
|
||||
async function get(urlPath) {
|
||||
export async function get(urlPath) {
|
||||
const url = new URL("https://localhost:4443");
|
||||
url.pathname = urlPath;
|
||||
let res = await fetch(url);
|
||||
@@ -191,16 +190,16 @@ let haveFactorioInstall;
|
||||
|
||||
const baseHostConfig = loadJSON("config-host.json");
|
||||
|
||||
let url = "https://localhost:4443/";
|
||||
let controlToken = jwt.sign({ aud: "user", user: "test" }, Buffer.from("TestSecretDoNotUse", "base64"));
|
||||
let instancesDir = path.join("temp", "test", "instances");
|
||||
let modsDir = path.join("temp", "test", "mods");
|
||||
let databaseDir = path.join("temp", "test", "database");
|
||||
let factorioDir = getFactorioDir(baseHostConfig);
|
||||
export let url = "https://localhost:4443/";
|
||||
export let controlToken = jwt.sign({ aud: "user", user: "test" }, Buffer.from("TestSecretDoNotUse", "base64"));
|
||||
export let instancesDir = path.join("temp", "test", "instances");
|
||||
export let modsDir = path.join("temp", "test", "mods");
|
||||
export let databaseDir = path.join("temp", "test", "database");
|
||||
export let factorioDir = getFactorioDir(baseHostConfig);
|
||||
let pluginListPath = path.join("temp", "test", "plugin-list.json");
|
||||
let controllerConfigPath = path.join("temp", "test", "config-controller.json");
|
||||
let hostConfigPath = path.join("temp", "test", "config-host.json");
|
||||
let controlConfigPath = path.join("temp", "test", "config-control.json");
|
||||
export let controllerConfigPath = path.join("temp", "test", "config-controller.json");
|
||||
export let hostConfigPath = path.join("temp", "test", "config-host.json");
|
||||
export let controlConfigPath = path.join("temp", "test", "config-control.json");
|
||||
|
||||
function childOptions(options) {
|
||||
return {
|
||||
@@ -210,29 +209,29 @@ function childOptions(options) {
|
||||
};
|
||||
}
|
||||
|
||||
function exec(command, options = {}) {
|
||||
export function exec(command, options = {}) {
|
||||
// Uncomment to show commands run in tests
|
||||
// console.log(command);
|
||||
return util.promisify(child_process.exec)(command, childOptions(options));
|
||||
}
|
||||
|
||||
function execController(...args) {
|
||||
export function execController(...args) {
|
||||
args[0] = `node --enable-source-maps ../../packages/controller ${args[0]}`;
|
||||
return exec(...args);
|
||||
}
|
||||
|
||||
function execHost(...args) {
|
||||
export function execHost(...args) {
|
||||
args[0] = `node --enable-source-maps ../../packages/host ${args[0]}`;
|
||||
return exec(...args);
|
||||
}
|
||||
|
||||
function execCtlProcess(...args) {
|
||||
export function execCtlProcess(...args) {
|
||||
args[0] = `node --enable-source-maps ../../packages/ctl ${args[0]}`;
|
||||
return exec(...args);
|
||||
}
|
||||
|
||||
let inExecCtl = false;
|
||||
async function execCtl(command) {
|
||||
export async function execCtl(command) {
|
||||
inExecCtl = true;
|
||||
process.chdir("temp/test");
|
||||
try {
|
||||
@@ -257,16 +256,16 @@ afterEach(function() {
|
||||
}
|
||||
});
|
||||
|
||||
async function sendRcon(instanceId, command) {
|
||||
export async function sendRcon(instanceId, command) {
|
||||
return await control.sendTo({ instanceId }, new lib.InstanceSendRconRequest(command));
|
||||
}
|
||||
|
||||
function getControl() {
|
||||
export function getControl() {
|
||||
return control;
|
||||
}
|
||||
|
||||
/** @returns {Promise<child_process.ChildProcess>} */
|
||||
function spawn(name, cmd, waitFor, options = {}) {
|
||||
export function spawn(name, cmd, waitFor, options = {}) {
|
||||
|
||||
const silent = process.env.SILENT_TEST;
|
||||
const bootstrap = !controllerProcess || !hostProcess;
|
||||
@@ -303,7 +302,7 @@ function spawn(name, cmd, waitFor, options = {}) {
|
||||
});
|
||||
}
|
||||
|
||||
function spawnNode(name, cmd, waitFor, options) {
|
||||
export function spawnNode(name, cmd, waitFor, options) {
|
||||
return spawn(name, `node --enable-source-maps ${cmd}`, waitFor, options);
|
||||
}
|
||||
|
||||
@@ -437,34 +436,3 @@ process.on("exit", () => {
|
||||
if (hostProcess) { hostProcess.kill(); }
|
||||
if (controllerProcess) { controllerProcess.kill(); }
|
||||
});
|
||||
|
||||
|
||||
module.exports = {
|
||||
TestControl,
|
||||
TestControlConnector,
|
||||
TestHostConnector,
|
||||
execController,
|
||||
execCtlProcess,
|
||||
slowTest,
|
||||
externalTest,
|
||||
requiresFactorio,
|
||||
get,
|
||||
exec,
|
||||
execCtl,
|
||||
execHost,
|
||||
sendRcon,
|
||||
getControl,
|
||||
spawn,
|
||||
spawnNode,
|
||||
|
||||
url,
|
||||
controlToken,
|
||||
instancesDir,
|
||||
modsDir,
|
||||
databaseDir,
|
||||
factorioDir,
|
||||
hasFactorio,
|
||||
controllerConfigPath,
|
||||
hostConfigPath,
|
||||
controlConfigPath,
|
||||
};
|
||||
@@ -1,14 +1,13 @@
|
||||
"use strict";
|
||||
const path = require("path");
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
const fs = require("node:fs/promises");
|
||||
import path from "node:path";
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
import fs from "node:fs/promises";
|
||||
|
||||
const { testMatrix } = require("../common");
|
||||
const {
|
||||
import { testMatrix } from "../common.js";
|
||||
import {
|
||||
slowTest, exec, execCtl, execCtlProcess, sendRcon, getControl,
|
||||
requiresFactorio, hasFactorio, instancesDir,
|
||||
} = require("./index");
|
||||
} from "./index.js";
|
||||
|
||||
const instId = 48;
|
||||
const instName = "Integration";
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const events = require("events");
|
||||
const fs = require("node:fs/promises");
|
||||
const jwt = require("jsonwebtoken");
|
||||
import assert from "node:assert/strict";
|
||||
import events from "node:events";
|
||||
import jwt from "jsonwebtoken";
|
||||
|
||||
const { TestControlConnector, TestHostConnector, TestControl, get, exec, url, slowTest } = require("./index");
|
||||
const { ConnectionClosed, ProtocolError, PolicyViolation, AuthenticationFailed } = require("@clusterio/lib");
|
||||
import { TestControlConnector, TestHostConnector, TestControl, get, exec, url, slowTest } from "./index.js";
|
||||
import { ConnectionClosed, ProtocolError, PolicyViolation, AuthenticationFailed } from "@clusterio/lib";
|
||||
|
||||
let token = jwt.sign({ aud: "user", user: "test" }, Buffer.from("TestSecretDoNotUse", "base64"));
|
||||
let tokenHost = jwt.sign({ aud: "host", host: 0 }, Buffer.from("TestSecretDoNotUse", "base64"));
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const JSZip = require("jszip");
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import JSZip from "jszip";
|
||||
import path from "node:path";
|
||||
|
||||
const { patch, SaveModule } = require("@clusterio/host/dist/node/src/patch");
|
||||
const lib = require("@clusterio/lib");
|
||||
import { patch, SaveModule } from "@clusterio/host/dist/node/src/patch.js";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
const { slowTest } = require("./index");
|
||||
import { slowTest } from "./index.js";
|
||||
|
||||
|
||||
// The server integration test is required to run before this one
|
||||
require("./server");
|
||||
import "./server.js";
|
||||
|
||||
describe("Integration of lib/factorio/patch", function() {
|
||||
describe("patch()", function() {
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { Host, Instance, InstanceConnection } = require("@clusterio/host");
|
||||
const { ControlConnection, Controller, HostConnection, InstanceRecord } = require("@clusterio/controller");
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { Host, Instance, InstanceConnection } from "@clusterio/host";
|
||||
import { ControlConnection, Controller, HostConnection, InstanceRecord } from "@clusterio/controller";
|
||||
|
||||
// Although there are no imports, the file has side-effects such as "before" which can effect tests
|
||||
require("./index");
|
||||
import "./index.js";
|
||||
|
||||
const addr = lib.Address.fromShorthand;
|
||||
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const events = require("events");
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import events from "node:events";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { InstanceManager } = require("@clusterio/controller");
|
||||
const { FactorioServer, _getFactorioVersion } = require("@clusterio/host/dist/node/src/server");
|
||||
const { logger } = lib;
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { InstanceManager } from "@clusterio/controller";
|
||||
import { FactorioServer, _getFactorioVersion } from "@clusterio/host/dist/node/src/server.js";
|
||||
import { logger } from "@clusterio/lib";
|
||||
|
||||
const { slowTest, factorioDir, requiresFactorio } = require("./index");
|
||||
import { slowTest, factorioDir, requiresFactorio } from "./index.js";
|
||||
|
||||
|
||||
describe("Integration of host/src/server", function() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const { ExponentialBackoff } = require("@clusterio/lib");
|
||||
import { ExponentialBackoff } from "@clusterio/lib";
|
||||
|
||||
describe("lib/ExponentialBackoff", function() {
|
||||
describe("class ExponentialBackoff", function() {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
/* eslint-disable node/no-sync */
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
const { LockFile } = require("@clusterio/lib");
|
||||
import { LockFile } from "@clusterio/lib";
|
||||
|
||||
const baseDir = path.join("temp", "test", "lock_file");
|
||||
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const path = require("path");
|
||||
const fs = require("node:fs/promises");
|
||||
const stream = require("node:stream");
|
||||
const JSZip = require("jszip"); // Added for creating mock zips
|
||||
import assert from "node:assert/strict";
|
||||
import path from "node:path";
|
||||
import fs from "node:fs/promises";
|
||||
import stream from "node:stream";
|
||||
import JSZip from "jszip"; // Added for creating mock zips
|
||||
|
||||
// Capture native fetch before any potential mocks are applied
|
||||
const nativeFetch = global.fetch;
|
||||
|
||||
const { ModStore, ModInfo, ModVersionEquality } = require("@clusterio/lib"); // Adjust path based on compiled output
|
||||
const { externalTest } = require("../integration");
|
||||
import { ModStore, ModInfo, ModVersionEquality } from "@clusterio/lib"; // Adjust path based on compiled output
|
||||
import { externalTest } from "../integration/index.js";
|
||||
|
||||
const MODS_DIR = path.join("temp", "test", "mod_store", "mods");
|
||||
const CACHE_FILE = path.join(MODS_DIR, "mod-info-cache.json");
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const { RateLimiter, wait } = require("@clusterio/lib");
|
||||
import { RateLimiter, wait } from "@clusterio/lib";
|
||||
|
||||
|
||||
describe("lib/RateLimiter", function() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
const assert = require("assert").strict;
|
||||
const { ValueCache, wait } = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import { ValueCache, wait } from "@clusterio/lib";
|
||||
|
||||
describe("ValueCache", function () {
|
||||
describe("constructor", function () {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
const assert = require("assert").strict;
|
||||
const { checkSingletonImport } = require("@clusterio/lib/dist/node/src/check_singleton_import");
|
||||
import assert from "node:assert/strict";
|
||||
import { checkSingletonImport } from "@clusterio/lib/dist/node/src/check_singleton_import.js";
|
||||
// Import lib so it sets the global indicating lib has been imported.
|
||||
require("@clusterio/lib");
|
||||
import "@clusterio/lib";
|
||||
|
||||
describe("lib/check_singleton_import", function() {
|
||||
it("Should throw an installation error if called twice", function() {
|
||||
assert.throws(
|
||||
() => checkSingletonImport(__filename),
|
||||
() => checkSingletonImport(import.meta.filename),
|
||||
{
|
||||
message: /Attempt to import duplicate copy of @clusterio\/lib/,
|
||||
code: "InstallationError",
|
||||
|
||||
+43
-11
@@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const mock = require("../mock");
|
||||
import * as lib from "@clusterio/lib";
|
||||
import * as mock from "../mock.js";
|
||||
|
||||
const addr = lib.Address.fromShorthand;
|
||||
|
||||
@@ -16,39 +15,68 @@ describe("lib/command", function() {
|
||||
let testControl = new mock.MockControl(controlConnector);
|
||||
let testController = new lib.Link(controllerConnector);
|
||||
testController.handle(
|
||||
lib.HostListRequest, () => [new lib.HostDetails("0.1", "Test Host", 11, false)]
|
||||
lib.HostListRequest, () => [
|
||||
new lib.HostDetails("0.1", "Test Host", 11, false),
|
||||
new lib.HostDetails("0.1", "22", 12, false),
|
||||
new lib.HostDetails("0.1", "12", 13, false),
|
||||
]
|
||||
);
|
||||
testController.handle(
|
||||
lib.InstanceDetailsListRequest, () => [new lib.InstanceDetails("Test Instance", 57, 4, undefined, "stopped")]
|
||||
lib.InstanceDetailsListRequest, () => [
|
||||
new lib.InstanceDetails("Test Instance", 57, 4, undefined, "stopped"),
|
||||
new lib.InstanceDetails("10", 58, 4, undefined, "stopped"),
|
||||
new lib.InstanceDetails("58", 59, 4, undefined, "stopped"),
|
||||
]
|
||||
);
|
||||
testController.handle(lib.RoleListRequest, () => [testRole.toJSON()]);
|
||||
let numericRole = lib.Role.fromJSON({ id: 29, name: "77", description: "Test", permissions: [] });
|
||||
testController.handle(lib.RoleListRequest, () => [testRole.toJSON(), numericRole.toJSON()]);
|
||||
|
||||
describe("resolveHost", function() {
|
||||
it("should pass an integer like string back", async function() {
|
||||
assert.equal(await lib.resolveHost(null, "123"), 123);
|
||||
it("should resolve an integer like string as an id", async function() {
|
||||
assert.equal(await lib.resolveHost(testControl, "11"), 11);
|
||||
});
|
||||
it("should resolve a host name with the controller", async function() {
|
||||
assert.equal(await lib.resolveHost(testControl, "Test Host"), 11);
|
||||
});
|
||||
it("should resolve an integer like name if no host has that id", async function() {
|
||||
assert.equal(await lib.resolveHost(testControl, "22"), 12);
|
||||
});
|
||||
it("should prefer the id over an integer like name", async function() {
|
||||
assert.equal(await lib.resolveHost(testControl, "12"), 12);
|
||||
});
|
||||
it("should throw if host is not found", async function() {
|
||||
await assert.rejects(
|
||||
lib.resolveHost(testControl, "invalid"),
|
||||
new lib.CommandError("No host named invalid")
|
||||
);
|
||||
await assert.rejects(
|
||||
lib.resolveHost(testControl, "123"),
|
||||
new lib.CommandError("No host named 123")
|
||||
);
|
||||
});
|
||||
});
|
||||
describe("resolveInstance", function() {
|
||||
it("should pass an integer like string back", async function() {
|
||||
assert.equal(await lib.resolveInstance(null, "123"), 123);
|
||||
it("should resolve an integer like string as an id", async function() {
|
||||
assert.equal(await lib.resolveInstance(testControl, "57"), 57);
|
||||
});
|
||||
it("should resolve an instance name with the controller", async function() {
|
||||
assert.equal(await lib.resolveInstance(testControl, "Test Instance"), 57);
|
||||
});
|
||||
it("should resolve an integer like name if no instance has that id", async function() {
|
||||
assert.equal(await lib.resolveInstance(testControl, "10"), 58);
|
||||
});
|
||||
it("should prefer the id over an integer like name", async function() {
|
||||
assert.equal(await lib.resolveInstance(testControl, "58"), 58);
|
||||
});
|
||||
it("should throw if instance is not found", async function() {
|
||||
await assert.rejects(
|
||||
lib.resolveInstance(testControl, "invalid"),
|
||||
new lib.CommandError("No instance named invalid")
|
||||
);
|
||||
await assert.rejects(
|
||||
lib.resolveInstance(testControl, "123"),
|
||||
new lib.CommandError("No instance named 123")
|
||||
);
|
||||
});
|
||||
});
|
||||
describe("retrieveRole", function() {
|
||||
@@ -58,6 +86,10 @@ describe("lib/command", function() {
|
||||
it("should retrieve a role by name from a string", async function() {
|
||||
assert.deepEqual(await lib.retrieveRole(testControl, "Test Role"), testRole);
|
||||
});
|
||||
it("should retrieve a role by an integer like name if no role has that id", async function() {
|
||||
assert.deepEqual(await lib.retrieveRole(testControl, "28"), testRole);
|
||||
assert.deepEqual(await lib.retrieveRole(testControl, "77"), numericRole);
|
||||
});
|
||||
it("should throw if role is not found", async function() {
|
||||
await assert.rejects(
|
||||
lib.retrieveRole(testControl, "invalid"),
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
const lib = require("@clusterio/lib");
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("path");
|
||||
const assert = require("assert").strict;
|
||||
import * as lib from "@clusterio/lib";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import assert from "node:assert/strict";
|
||||
const CA = lib.ConfigAccess;
|
||||
|
||||
|
||||
@@ -396,6 +395,15 @@ describe("lib/config/classes", function() {
|
||||
const json = JSON.parse(await fs.readFile(filepath, "utf8"));
|
||||
assert.deepEqual(json, testInstance.toJSON());
|
||||
});
|
||||
it("should not be readable by other users", async function() {
|
||||
if (process.platform === "win32") {
|
||||
this.skip();
|
||||
}
|
||||
const testInstance = new TestConfig("local", { "alpha.foo": "a" }, filepath);
|
||||
testInstance.set("alpha.foo", "b"); // Sets the dirty flag
|
||||
await testInstance.save();
|
||||
assert.equal((await fs.stat(filepath)).mode & 0o777, 0o600);
|
||||
});
|
||||
it("should clear the dirty flag after saving", async function() {
|
||||
const testInstance = new TestConfig("local", { "alpha.foo": "a" }, filepath);
|
||||
testInstance.set("alpha.foo", "b"); // Sets the dirty flag
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
const lib = require("@clusterio/lib");
|
||||
const assert = require("assert").strict;
|
||||
import * as lib from "@clusterio/lib";
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
// Each migration test should indicate which version introduced the migration
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
const validators = lib.Config.validators;
|
||||
const { ControllerConfig, HostConfig, InstanceConfig, ControlConfig } = lib;
|
||||
import { ControllerConfig, HostConfig, InstanceConfig, ControlConfig } from "@clusterio/lib";
|
||||
|
||||
describe("lib/config/validators", function() {
|
||||
describe("all", function() {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const { HostDetails } = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import { HostDetails } from "@clusterio/lib";
|
||||
|
||||
const { testMatrix, testRoundTripJsonSerialisable } = require("../../common");
|
||||
import { testMatrix, testRoundTripJsonSerialisable } from "../../common.js";
|
||||
|
||||
describe("lib/data/HostDetails", function () {
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const { InstanceDetails } = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import { InstanceDetails } from "@clusterio/lib";
|
||||
|
||||
const { testMatrix, testRoundTripJsonSerialisable } = require("../../common");
|
||||
import { testMatrix, testRoundTripJsonSerialisable } from "../../common.js";
|
||||
|
||||
describe("lib/data/InstanceDetails", function () {
|
||||
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const libBuildMod = require("@clusterio/lib/build_mod");
|
||||
const { ModInfo, ModDependency } = lib;
|
||||
import * as lib from "@clusterio/lib";
|
||||
import * as libBuildMod from "@clusterio/lib/build_mod.js";
|
||||
import { ModInfo, ModDependency } from "@clusterio/lib";
|
||||
|
||||
const { testMatrix, testRoundTripJsonSerialisable } = require("../../common");
|
||||
import { testMatrix, testRoundTripJsonSerialisable } from "../../common.js";
|
||||
|
||||
describe("lib/data/ModInfo", function() {
|
||||
describe("class ModDependency", function() {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const zlib = require("zlib");
|
||||
import assert from "node:assert/strict";
|
||||
import zlib from "node:zlib";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { ModInfo, ModPack, getInstalledModUpdates, applyModRecordAdvisories } = lib;
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { ModInfo, ModPack, getInstalledModUpdates, applyModRecordAdvisories } from "@clusterio/lib";
|
||||
|
||||
|
||||
describe("lib/data/ModPack", function() {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
describe("lib/data/Role", function() {
|
||||
let defaultPermissions;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { SystemInfo } = lib;
|
||||
import { SystemInfo } from "@clusterio/lib";
|
||||
|
||||
|
||||
describe("lib/data/SystemInfo", function() {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const { UserDetails, PlayerStats } = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import { UserDetails, PlayerStats } from "@clusterio/lib";
|
||||
|
||||
const { testMatrix, testRoundTripJsonSerialisable } = require("../../common");
|
||||
import { testMatrix, testRoundTripJsonSerialisable } from "../../common.js";
|
||||
|
||||
describe("lib/data/UserDetails", function () {
|
||||
it("should be round trip serialisable", function () {
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
const { Address } = lib;
|
||||
import assert from "node:assert/strict";
|
||||
import { Address } from "@clusterio/lib";
|
||||
|
||||
describe("lib/data/messages_core", function() {
|
||||
describe("class Address", function() {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
const { testMatrix, testRoundTripJsonSerialisable } = require("../../common");
|
||||
import { testMatrix, testRoundTripJsonSerialisable } from "../../common.js";
|
||||
|
||||
describe("lib/data/version", function() {
|
||||
describe("isVersionEquality()", function() {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
describe("lib/database", function() {
|
||||
describe("mapToObject()", function() {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const events = require("events");
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("path");
|
||||
import events from "node:events";
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
class MockDatastoreProvider extends lib.DatastoreProvider {
|
||||
constructor() {
|
||||
|
||||
+2
-3
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
describe("lib/errors", function() {
|
||||
describe("class InvalidMessage", function() {
|
||||
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
const assert = require("assert").strict;
|
||||
const { readFile } = require("node:fs/promises");
|
||||
import assert from "node:assert/strict";
|
||||
import { readFile } from "node:fs/promises";
|
||||
|
||||
const { fetchFactorioVersions } = require("@clusterio/lib");
|
||||
const { slowTest, externalTest } = require("../../integration");
|
||||
import { fetchFactorioVersions } from "@clusterio/lib";
|
||||
import { slowTest, externalTest } from "../../integration/index.js";
|
||||
|
||||
describe("FactorioVersions", function() {
|
||||
describe("fetchFactorioVersions", function() {
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
const assert = require("assert").strict;
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const { fetchLatestReleases, resolveReleaseChannel } = require("@clusterio/lib");
|
||||
const { slowTest, externalTest } = require("../../integration");
|
||||
import { fetchLatestReleases, resolveReleaseChannel } from "@clusterio/lib";
|
||||
import { slowTest, externalTest } from "../../integration/index.js";
|
||||
|
||||
describe("LatestReleases", function() {
|
||||
describe("fetchLatestReleases", function() {
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const zlib = require("zlib");
|
||||
import assert from "node:assert/strict";
|
||||
import zlib from "node:zlib";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
const testStrings = require("./test_strings");
|
||||
const testSettings = require("./test_settings");
|
||||
import * as testStrings from "./test_strings.js";
|
||||
import * as testSettings from "./test_settings.js";
|
||||
|
||||
|
||||
// Simple linear congruential random number generator
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Lines for testing the factorio output
|
||||
|
||||
"use strict";
|
||||
let testLines = new Map([
|
||||
export const testLines = new Map([
|
||||
[
|
||||
" 1.306 Info RemoteCommandProcessor.cpp:131: Starting RCON interface at port 4000",
|
||||
{
|
||||
@@ -219,7 +217,3 @@ let testLines = new Map([
|
||||
},
|
||||
],
|
||||
]);
|
||||
|
||||
module.exports = {
|
||||
testLines,
|
||||
};
|
||||
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
const default_map_gen_settings = {
|
||||
export const default_map_gen_settings = {
|
||||
autoplace_controls: {
|
||||
"coal": { frequency: 1, size: 1, richness: 1 },
|
||||
"copper-ore": { frequency: 1, size: 1, richness: 1 },
|
||||
@@ -37,7 +36,7 @@ const default_map_gen_settings = {
|
||||
water: 1,
|
||||
};
|
||||
|
||||
const default_map_settings = {
|
||||
export const default_map_settings = {
|
||||
pollution: {
|
||||
enabled: true,
|
||||
diffusion_ratio: 0.02,
|
||||
@@ -140,7 +139,7 @@ const default_map_settings = {
|
||||
},
|
||||
};
|
||||
|
||||
const modified_map_gen_settings = {
|
||||
export const modified_map_gen_settings = {
|
||||
autoplace_controls: {
|
||||
"coal": { frequency: 1, size: 1, richness: 1 },
|
||||
"copper-ore": { frequency: 0.5, size: 1, richness: 1 },
|
||||
@@ -196,7 +195,7 @@ const modified_map_gen_settings = {
|
||||
water: 0.3333333432674408,
|
||||
};
|
||||
|
||||
const modified_map_settings = {
|
||||
export const modified_map_settings = {
|
||||
pollution: {
|
||||
enabled: true,
|
||||
diffusion_ratio: 0.02,
|
||||
@@ -299,7 +298,7 @@ const modified_map_settings = {
|
||||
},
|
||||
};
|
||||
|
||||
const modified_v2_map_gen_settings = {
|
||||
export const modified_v2_map_gen_settings = {
|
||||
autoplace_controls: {
|
||||
"coal": { frequency: 1, size: 1, richness: 1 },
|
||||
"copper-ore": { frequency: 0.5, size: 1, richness: 1 },
|
||||
@@ -362,7 +361,7 @@ const modified_v2_map_gen_settings = {
|
||||
territory_settings: null,
|
||||
};
|
||||
|
||||
const modified_v2_map_settings = {
|
||||
export const modified_v2_map_settings = {
|
||||
pollution: {
|
||||
enabled: true,
|
||||
diffusion_ratio: 0.02,
|
||||
@@ -467,7 +466,7 @@ const modified_v2_map_settings = {
|
||||
},
|
||||
};
|
||||
|
||||
const modified_v2_1_map_gen_settings = {
|
||||
export const modified_v2_1_map_gen_settings = {
|
||||
"autoplace_controls": {
|
||||
"coal": { "frequency": 1, "size": 1, "richness": 1 },
|
||||
"copper-ore": { "frequency": 0.5, "size": 1, "richness": 1 },
|
||||
@@ -516,7 +515,7 @@ const modified_v2_1_map_gen_settings = {
|
||||
"territory_settings": null,
|
||||
};
|
||||
|
||||
const modified_v2_1_map_settings = {
|
||||
export const modified_v2_1_map_settings = {
|
||||
"pollution": {
|
||||
"enabled": true,
|
||||
"diffusion_ratio": 0.02,
|
||||
@@ -615,7 +614,7 @@ const modified_v2_1_map_settings = {
|
||||
},
|
||||
};
|
||||
|
||||
const modified_v2_1_13_map_settings = {
|
||||
export const modified_v2_1_13_map_settings = {
|
||||
...modified_v2_1_map_settings,
|
||||
"enemy_expansion": {
|
||||
...modified_v2_1_map_settings.enemy_expansion,
|
||||
@@ -623,7 +622,7 @@ const modified_v2_1_13_map_settings = {
|
||||
},
|
||||
};
|
||||
|
||||
const modified_space_age_map_gen_settings = {
|
||||
export const modified_space_age_map_gen_settings = {
|
||||
autoplace_controls: {
|
||||
"aquilo_crude_oil": { frequency: 1, size: 1, richness: 1 },
|
||||
"calcite": { frequency: 1, size: 1, richness: 1 },
|
||||
@@ -701,16 +700,3 @@ const modified_space_age_map_gen_settings = {
|
||||
no_enemies_mode: false,
|
||||
territory_settings: null,
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
default_map_gen_settings,
|
||||
default_map_settings,
|
||||
modified_map_gen_settings,
|
||||
modified_map_settings,
|
||||
modified_v2_map_gen_settings,
|
||||
modified_v2_map_settings,
|
||||
modified_v2_1_map_gen_settings,
|
||||
modified_v2_1_map_settings,
|
||||
modified_v2_1_13_map_settings,
|
||||
modified_space_age_map_gen_settings,
|
||||
};
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
// Exchange strings for testing with
|
||||
|
||||
const default_ = `
|
||||
export default `
|
||||
>>>eNpjZGBkUGQAgwZ7EOZgSc5PzIHxQJgrOb+gILVIN78oFVmYM
|
||||
7moNCVVNz8TVXFqXmpupW5SYjGKYo7Movw8dBNYi0vy81BFSopSU
|
||||
4uRRbhLixLzMktz0fUyMF5imubZ0CLHAML/6xkU/v8HYSDrAdAvI
|
||||
@@ -14,7 +13,7 @@ MPlQMQJEAG2EO4yRgjTod+B0UEeJiuJUALUb8SA7IYUhA9Pwqw9j
|
||||
GQ/mkMwIwLZH2giKg5YooELZGEKnHjBDHcNMDwvsMN4DvMdGJlBD
|
||||
JCqL0AxCA8kAzMKQgs4gIObmQEBgGmjrO/lHgDxa6G4<<<`;
|
||||
|
||||
const modified = `
|
||||
export const modified = `
|
||||
>>>eNp1UzFs00AUvZ8mbRIEypCBSlCCyFAhOQqBKULxlQUxMCCxgnCc
|
||||
S2rh2On5LAgMZOjAgISEurQLXSmCBTGwRWKhEkgIJraiMgBiaGmFOiC
|
||||
FO5/PsUz6pfv+9/6/99+/kwEBOo2k6c83NhrZtOkaNkIDXa286fZ6hG
|
||||
@@ -31,7 +30,7 @@ jnh3gmXQRElVwYyxI8x4FMqOzsu4edrKK6hNZ5wU7V9G+ufEFL+7yHi
|
||||
cySQMp7wDHnRsBW571ORGn6fH2fUDj/FwV0iUbXPMbmTP7akkt8ChiL
|
||||
/BPceEs3j1M3iz71/ObT9tA==<<<`;
|
||||
|
||||
const modified_v2 = `
|
||||
export const modified_v2 = `
|
||||
>>>eNp1Uz9oU0EY/y5N2iRWzRCFitSAGURIjNEpSN7VRRwcBFeJl5dL
|
||||
+ujLe+3de9XoYIYODoogXdrFrlZ0EQe3gIsFBdHJrVIHBYdWi3QQ4l3
|
||||
u3csz1Q++7333+31/75IYAJwRCpNx0yU2QNfQmjbd+XnKCi6jgg/hlM
|
||||
@@ -49,7 +48,7 @@ Ln6IET6h2alhiMgvQ3SGxnDDDd32daT/yCD5fQ8R3WMEyeN/PENaNmy
|
||||
E5utYOI24z/cT+oQf48FdgozaFZg6qX+1KqW+GYyy4qNZgFNY/0IAHj
|
||||
RI5Q/27QvL<<<`;
|
||||
|
||||
const modified_v2_1 = `
|
||||
export const modified_v2_1 = `
|
||||
>>>eNp1U89rE0EUftM0NYlVc4iCIjWHHkRICNFTkezoRTx4ELxKnGwm
|
||||
unSz087uVlsP5uDBg1CQXvSiVyt6EY9CwIu9if4DlXqwt1aK9CDEeZm
|
||||
dyZrgg/f49nu/37BTQCAPGYDZaVcwH6DnGC24YmmJy4qQHAAsnXdl3O
|
||||
@@ -65,7 +64,7 @@ JYkZplFakZG9jCkjt5gyQ4nHFv3qqTPmsjWiYeiVKOkP57RB9xB0Dvk
|
||||
X9skPmJ46b3GGNscC4FCtiwbc3PTPrUX46YL/qSDp8BMOqAJI8C+u/S
|
||||
peyl8e7GC3Ce2le3AIs019Y//gU3lOV1<<<`;
|
||||
|
||||
const modified_space_age = `
|
||||
export const modified_space_age = `
|
||||
>>>eNp1VEFoE0EUnUkb27TWBomFSqkBexAhMVZPRbJbL+LBg+BV1slm
|
||||
kgzd7LYzs9HYgz304EEQpJf2Yq9W9CIevBW8WFAQPXmr1IOCh1aL9CD
|
||||
UmZ2dzW4aB2by972Z9//7MyQFALggJpjIogWfOJ5lU7+KLY84ACwZeg
|
||||
@@ -86,7 +85,7 @@ Gx0+5gy4RUpPimXd3JJg0hSVAZVaD42oXlGs+OdLeL8NIjXUO043NJp
|
||||
38bydxUydeQi4j66kCmzxzUMyYTVaPneF1Uj+vlxQH+ZT82gl0Du2he
|
||||
Y+lJ/JEpK/WZNmBM/mgXgnKlfCACLzljjH+s/hYo=<<<`;
|
||||
|
||||
const modified_v2_1_13 = `
|
||||
export const modified_v2_1_13 = `
|
||||
>>>eNp1U89rE0EUftMmNYm15hAFRWoOPYiQEKKgFMmOXsSDB0HwJHGy
|
||||
mejSzU47u1utHszBgwdBkF70olcrehHvAS/2JvUfqNSDvbVSpAehzsv
|
||||
sTNYEH7zHt9/7/YadAAIzSmE64wrmA/QcowVXLC5yWRGSA4Cl866M27
|
||||
@@ -101,12 +100,3 @@ JYkZpmFakZGd1AkjtxhSQjYziizPKvHmmTPmUDWuYoiVKOgP57RB9yS
|
||||
0Dvo1NMEfJJWw1i+YLmuywM1C1jwbPKaGnjffEMETl1yE9Qxu/9C7rp
|
||||
u3nVP+RQebGLpzeY4SxwbkUKGDDtjU/J9P3/nrIfNHXdPAWgFF7JHkZ
|
||||
0L+YLmXPjcc3XoAz1D69BVjk1sULxb83nuUA<<<`;
|
||||
|
||||
module.exports = {
|
||||
default: default_,
|
||||
modified,
|
||||
modified_v2,
|
||||
modified_v2_1,
|
||||
modified_v2_1_13,
|
||||
modified_space_age,
|
||||
};
|
||||
+16
-7
@@ -1,11 +1,10 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const http = require("node:http");
|
||||
const path = require("path");
|
||||
const util = require("node:util");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import http from "node:http";
|
||||
import path from "node:path";
|
||||
import util from "node:util";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
describe("lib/file_ops", function() {
|
||||
let baseDir = path.join("temp", "test", "file_ops");
|
||||
@@ -101,6 +100,16 @@ describe("lib/file_ops", function() {
|
||||
await assert.rejects(fs.access(target.replace(".txt", ".tmp.txt")), "temporary was left behind");
|
||||
assert.equal(await fs.readFile(target, "utf8"), "current");
|
||||
});
|
||||
it("should apply mode to a leftover temporary file", async function() {
|
||||
if (process.platform === "win32") {
|
||||
this.skip();
|
||||
}
|
||||
let target = path.join(baseDir, "safe", "mode.txt");
|
||||
await fs.writeFile(target.replace(".txt", ".tmp.txt"), "stale", { mode: 0o644 });
|
||||
await lib.safeOutputFile(target, "private", { mode: 0o600 });
|
||||
assert.equal((await fs.stat(target)).mode & 0o777, 0o600);
|
||||
assert.equal(await fs.readFile(target, "utf8"), "private");
|
||||
});
|
||||
it("should handle creating file in current working directory", async function() {
|
||||
let target = "temporary-file-made-to-test-cwd.txt";
|
||||
try {
|
||||
|
||||
+4
-5
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
|
||||
describe("lib/hash", function() {
|
||||
|
||||
+2
-3
@@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
import assert from "node:assert/strict";
|
||||
const hrtime = process.hrtime.bigint;
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
|
||||
describe("lib/helpers", function() {
|
||||
|
||||
+3
-4
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const lib = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
describe("lib/ini", function() {
|
||||
describe("parse()", function() {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const events = require("events");
|
||||
import assert from "node:assert/strict";
|
||||
import events from "node:events";
|
||||
|
||||
const mock = require("../../mock");
|
||||
const lib = require("@clusterio/lib");
|
||||
import * as mock from "../../mock.js";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
|
||||
describe("lib/link/connectors", function() {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const events = require("events");
|
||||
import assert from "node:assert/strict";
|
||||
import events from "node:events";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const mock = require("../../mock");
|
||||
import * as lib from "@clusterio/lib";
|
||||
import * as mock from "../../mock.js";
|
||||
|
||||
const addr = lib.Address.fromShorthand;
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
const { testLines } = require("./factorio/lines");
|
||||
const lib = require("@clusterio/lib");
|
||||
import { testLines } from "./factorio/lines.js";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
|
||||
describe("lib/logging_utils.js", function() {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
|
||||
describe("lib/lua_tools", function() {
|
||||
|
||||
+23
-4
@@ -1,11 +1,30 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const mock = require("../mock");
|
||||
const lib = require("@clusterio/lib");
|
||||
import * as mock from "../mock.js";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
|
||||
describe("lib/plugin", function() {
|
||||
describe("pluginNeedsWebBuild()", function() {
|
||||
it("should be false for plugins with only host, instance or ctl code", function() {
|
||||
assert.equal(lib.pluginNeedsWebBuild({ name: "foo", title: "Foo" }), false);
|
||||
assert.equal(lib.pluginNeedsWebBuild({
|
||||
name: "foo", title: "Foo", hostEntrypoint: "host.js", instanceEntrypoint: "instance.js",
|
||||
ctlEntrypoint: "ctl.js", messages: [],
|
||||
}), false);
|
||||
});
|
||||
it("should be true for plugins with web or controller code or config fields", function() {
|
||||
assert.equal(lib.pluginNeedsWebBuild({ name: "foo", title: "Foo", webEntrypoint: "web.js" }), true);
|
||||
assert.equal(lib.pluginNeedsWebBuild({
|
||||
name: "foo", title: "Foo", controllerEntrypoint: "controller.js",
|
||||
}), true);
|
||||
for (const field of [
|
||||
"controllerConfigFields", "hostConfigFields", "instanceConfigFields", "controlConfigFields",
|
||||
]) {
|
||||
assert.equal(lib.pluginNeedsWebBuild({ name: "foo", title: "Foo", [field]: {} }), true, field);
|
||||
}
|
||||
});
|
||||
});
|
||||
describe("invokeHook()", function() {
|
||||
let betaTestCalled = false;
|
||||
let plugins = new Map([
|
||||
|
||||
+16
-15
@@ -1,10 +1,10 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("path");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { BaseControllerPlugin } = require("@clusterio/controller");
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { BaseControllerPlugin } from "@clusterio/controller";
|
||||
|
||||
|
||||
describe("lib/plugin_loader", function() {
|
||||
@@ -19,7 +19,7 @@ describe("lib/plugin_loader", function() {
|
||||
await fs.mkdir(pluginPath, { recursive: true });
|
||||
await fs.writeFile(
|
||||
path.join(pluginPath, "index.js"),
|
||||
`module.exports.plugin = { name: "${infoName}" };`
|
||||
`export const plugin = { name: "${infoName}" };`
|
||||
);
|
||||
await fs.writeFile(
|
||||
path.join(pluginPath, "package.json"),
|
||||
@@ -47,6 +47,7 @@ describe("lib/plugin_loader", function() {
|
||||
name: "test",
|
||||
version: "0.0.1",
|
||||
npmPackage: undefined,
|
||||
packagePath: path.resolve(path.join(testPlugin, "package.json")),
|
||||
requirePath: path.resolve(testPlugin),
|
||||
webStaticPath: path.resolve(path.join(testPlugin, "dist", "web", "static")),
|
||||
}]
|
||||
@@ -55,7 +56,7 @@ describe("lib/plugin_loader", function() {
|
||||
it("should reject on broken plugin", async function() {
|
||||
let brokenMessage;
|
||||
try {
|
||||
require(path.resolve(brokenPlugin));
|
||||
await import(pathToFileURL(path.resolve(path.join(brokenPlugin, "index.js"))));
|
||||
} catch (err) {
|
||||
brokenMessage = err.message;
|
||||
}
|
||||
@@ -83,7 +84,7 @@ describe("lib/plugin_loader", function() {
|
||||
|
||||
await writeEntrypoint(missingClass, "");
|
||||
await writeEntrypoint(
|
||||
wrongParentClass, "class ControllerPlugin {}\n module.exports = { ControllerPlugin };\n"
|
||||
wrongParentClass, "export class ControllerPlugin {};\n"
|
||||
);
|
||||
});
|
||||
it("should throw if class is missing from entrypoint", async function() {
|
||||
@@ -91,13 +92,13 @@ describe("lib/plugin_loader", function() {
|
||||
await assert.rejects(
|
||||
lib.loadPluginClass(
|
||||
"test",
|
||||
path.posix.join(requirePath, "controller"),
|
||||
path.posix.join(requirePath, "controller.js"),
|
||||
"ControllerPlugin",
|
||||
BaseControllerPlugin,
|
||||
),
|
||||
{
|
||||
message:
|
||||
`PluginError: Expected ${path.posix.join(requirePath, "controller")} ` +
|
||||
`PluginError: Expected ${path.posix.join(requirePath, "controller.js")} ` +
|
||||
"to export a class named ControllerPlugin",
|
||||
}
|
||||
);
|
||||
@@ -107,14 +108,14 @@ describe("lib/plugin_loader", function() {
|
||||
await assert.rejects(
|
||||
lib.loadPluginClass(
|
||||
"test",
|
||||
path.posix.join(requirePath, "controller"),
|
||||
path.posix.join(requirePath, "controller.js"),
|
||||
"ControllerPlugin",
|
||||
BaseControllerPlugin,
|
||||
),
|
||||
{
|
||||
message:
|
||||
"PluginError: Expected ControllerPlugin exported from " +
|
||||
`${path.posix.join(requirePath, "controller")} to be a subclass of BaseControllerPlugin`,
|
||||
`${path.posix.join(requirePath, "controller.js")} to be a subclass of BaseControllerPlugin`,
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -151,7 +152,7 @@ describe("lib/plugin_loader", function() {
|
||||
await fs.mkdir(pluginPath, { recursive: true });
|
||||
await fs.writeFile(
|
||||
path.join(pluginPath, "index.js"),
|
||||
`module.exports.plugin = { name: "${name}" };`
|
||||
`export const plugin = { name: "${name}" };`
|
||||
);
|
||||
await fs.writeFile(
|
||||
path.join(pluginPath, "package.json"),
|
||||
@@ -194,7 +195,7 @@ describe("lib/plugin_loader", function() {
|
||||
await fs.mkdir(path.join(deepPluginPath, "dist"));
|
||||
await fs.writeFile(
|
||||
path.join(deepPluginPath, "dist", "index.js"),
|
||||
'module.exports.plugin = { name: "deep" };'
|
||||
'export const plugin = { name: "deep" };'
|
||||
);
|
||||
|
||||
// Create an npm module that is not a plugin
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const prometheus = require("@clusterio/lib");
|
||||
import * as prometheus from "@clusterio/lib";
|
||||
|
||||
|
||||
describe("lib/prometheus", function() {
|
||||
|
||||
+16
-3
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
describe("rce_ops", function() {
|
||||
describe("updatePackage", function() {
|
||||
@@ -29,6 +28,20 @@ describe("rce_ops", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("handleUpdateAll", function() {
|
||||
it("updates the core package and all npm plugins in one command", async function() {
|
||||
const _audit = lib.logger.audit;
|
||||
const messages = [];
|
||||
lib.logger.audit = (msg) => { messages.push(msg); };
|
||||
try {
|
||||
await lib.handleUpdateAll("core", [{ npmPackage: "foo" }, { name: "local" }, { npmPackage: "bar" }]);
|
||||
} finally {
|
||||
lib.logger.audit = _audit;
|
||||
}
|
||||
assert.deepEqual(messages, ["RCE | npm update --save core foo bar"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("handlePluginInstall", function() {
|
||||
const _fetch = global.fetch;
|
||||
before(function() {
|
||||
|
||||
+6
-7
@@ -1,11 +1,10 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const path = require("path");
|
||||
const stream = require("stream");
|
||||
const util = require("util");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import stream from "node:stream";
|
||||
import util from "node:util";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
const finished = util.promisify(stream.finished);
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const events = require("events");
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
const { MockController, MockConnector, MockControl } = require("../mock");
|
||||
const { testMatrix, testRoundTripJsonSerialisable } = require("../common");
|
||||
import events from "node:events";
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { MockController, MockConnector, MockControl } from "../mock.js";
|
||||
import { testMatrix, testRoundTripJsonSerialisable } from "../common.js";
|
||||
|
||||
const addr = lib.Address.fromShorthand;
|
||||
|
||||
|
||||
+43
-3
@@ -1,6 +1,5 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
|
||||
describe("lib/users", function() {
|
||||
@@ -44,4 +43,45 @@ describe("lib/users", function() {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("registerPluginPermissions()", function() {
|
||||
it("should define the permissions declared by plugins", function() {
|
||||
lib.registerPluginPermissions([
|
||||
{ name: "foo", permissions: [
|
||||
{ name: "foo.first", title: "First", description: "The first" },
|
||||
{ name: "foo.second", title: "Second", description: "The second", grantByDefault: true },
|
||||
]},
|
||||
{ name: "bar" },
|
||||
{ name: "baz", permissions: [] },
|
||||
]);
|
||||
assert(lib.permissions.has("foo.first"), "foo.first was not defined");
|
||||
assert.equal(lib.permissions.get("foo.first").grantByDefault, false);
|
||||
assert(lib.permissions.has("foo.second"), "foo.second was not defined");
|
||||
assert.equal(lib.permissions.get("foo.second").grantByDefault, true);
|
||||
});
|
||||
|
||||
it("should throw if the name does not start with the plugin name", function() {
|
||||
assert.throws(
|
||||
() => lib.registerPluginPermissions([
|
||||
{ name: "foo", permissions: [{ name: "bar.spam", title: "Spam", description: "Spam" }] },
|
||||
]),
|
||||
new Error("Expected name of permission 'bar.spam' for foo to start with 'foo.'")
|
||||
);
|
||||
assert.throws(
|
||||
() => lib.registerPluginPermissions([
|
||||
{ name: "foo", permissions: [{ title: "Spam", description: "Spam" }] },
|
||||
]),
|
||||
new Error("Expected name of permission 'undefined' for foo to start with 'foo.'")
|
||||
);
|
||||
});
|
||||
|
||||
it("should throw on already defined permission", function() {
|
||||
assert.throws(
|
||||
() => lib.registerPluginPermissions([
|
||||
{ name: "foo", permissions: [{ name: "foo.first", title: "First", description: "The first" }] },
|
||||
]),
|
||||
new Error("Permission 'foo.first' is already defined")
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
+3
-4
@@ -1,8 +1,7 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const JSZip = require("jszip");
|
||||
import assert from "node:assert/strict";
|
||||
import JSZip from "jszip";
|
||||
|
||||
const { findRoot } = require("@clusterio/lib");
|
||||
import { findRoot } from "@clusterio/lib";
|
||||
|
||||
|
||||
describe("lib/factorio", function() {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
"use strict";
|
||||
const { ModPack } = require("@clusterio/lib");
|
||||
import { ModPack } from "@clusterio/lib";
|
||||
|
||||
const pack = new ModPack();
|
||||
pack.name = "test-settings";
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const fs = require("node:fs/promises");
|
||||
const os = require("node:os");
|
||||
const path = require("node:path");
|
||||
const lib = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
const { Controller, ControlConnection } = require("@clusterio/controller");
|
||||
const { testMatrix, testRoundTripJsonSerialisable } = require("../common");
|
||||
import { Controller, ControlConnection } from "@clusterio/controller";
|
||||
import { testMatrix, testRoundTripJsonSerialisable } from "../common.js";
|
||||
|
||||
describe("messages/controller", function() {
|
||||
/** @type {Controller} */
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
const { Host } = require("@clusterio/host");
|
||||
const { testMatrix, testRoundTripJsonSerialisable } = require("../common");
|
||||
import { Host } from "@clusterio/host";
|
||||
import { testMatrix, testRoundTripJsonSerialisable } from "../common.js";
|
||||
|
||||
describe("messages/host", function() {
|
||||
/** @type {Host} */
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
import assert from "node:assert/strict";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { ModDependencyResolveRequest, ModDependency, ModInfo } = lib;
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { ModDependencyResolveRequest, ModDependency, ModInfo } from "@clusterio/lib";
|
||||
|
||||
const { testMatrix, testRoundTripJsonSerialisable } = require("../common");
|
||||
import { testMatrix, testRoundTripJsonSerialisable } from "../common.js";
|
||||
|
||||
const { Controller, ControlConnection } = require("@clusterio/controller");
|
||||
const { externalTest } = require("../integration");
|
||||
import { Controller, ControlConnection } from "@clusterio/controller";
|
||||
import { externalTest } from "../integration/index.js";
|
||||
|
||||
describe("messages/mod", function() {
|
||||
/** @type {Controller} */
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const lib = require("@clusterio/lib");
|
||||
import assert from "node:assert/strict";
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
const { Controller, ControlConnection } = require("@clusterio/controller");
|
||||
const { Host } = require("@clusterio/host");
|
||||
import { Controller, ControlConnection } from "@clusterio/controller";
|
||||
import { Host } from "@clusterio/host";
|
||||
|
||||
describe("messages/plugin", function() {
|
||||
/** @type {Host} */
|
||||
@@ -134,6 +133,61 @@ describe("messages/plugin", function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe("UpdateAllRequest", function() {
|
||||
function checkedPermissions(dst) {
|
||||
const permissions = [];
|
||||
const user = { checkPermission(permission) { permissions.push(permission); } };
|
||||
lib.UpdateAllRequest.permission(user, { dst: lib.Address.fromShorthand(dst) });
|
||||
return permissions;
|
||||
}
|
||||
it("requires controller and plugin update permissions on the controller", function() {
|
||||
assert.deepEqual(checkedPermissions("controller"), ["core.controller.update", "core.plugin.update"]);
|
||||
});
|
||||
it("requires host and plugin update permissions on a host", function() {
|
||||
assert.deepEqual(checkedPermissions({ hostId: 1 }), ["core.host.update", "core.plugin.update"]);
|
||||
});
|
||||
it("runs on the controller", async function() {
|
||||
controller.pluginInfos = [{ npmPackage: "foo" }];
|
||||
controller.config.set("controller.allow_remote_updates", true);
|
||||
controller.config.set("controller.allow_plugin_updates", true);
|
||||
await controlConnection.handleUpdateAllRequest(new lib.UpdateAllRequest());
|
||||
});
|
||||
it("rejects if remote updates are disabled on the controller", async function() {
|
||||
controller.config.set("controller.allow_remote_updates", false);
|
||||
await assert.rejects(
|
||||
controlConnection.handleUpdateAllRequest(new lib.UpdateAllRequest()),
|
||||
/Remote updates are disabled on this machine/
|
||||
);
|
||||
});
|
||||
it("rejects if plugin updates are disabled on the controller", async function() {
|
||||
controller.config.set("controller.allow_plugin_updates", false);
|
||||
await assert.rejects(
|
||||
controlConnection.handleUpdateAllRequest(new lib.UpdateAllRequest()),
|
||||
/Plugin updates are disabled on this machine/
|
||||
);
|
||||
});
|
||||
it("runs on a host", async function() {
|
||||
host.pluginInfos = [{ npmPackage: "foo" }];
|
||||
host.config.set("host.allow_remote_updates", true);
|
||||
host.config.set("host.allow_plugin_updates", true);
|
||||
await host.handleUpdateAllRequest(new lib.UpdateAllRequest());
|
||||
});
|
||||
it("rejects if remote updates are disabled on the host", async function() {
|
||||
host.config.set("host.allow_remote_updates", false);
|
||||
await assert.rejects(
|
||||
host.handleUpdateAllRequest(new lib.UpdateAllRequest()),
|
||||
/Remote updates are disabled on this machine/
|
||||
);
|
||||
});
|
||||
it("rejects if plugin updates are disabled on the host", async function() {
|
||||
host.config.set("host.allow_plugin_updates", false);
|
||||
await assert.rejects(
|
||||
host.handleUpdateAllRequest(new lib.UpdateAllRequest()),
|
||||
/Plugin updates are disabled on this machine/
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("PluginInstallRequest", function() {
|
||||
const _fetch = global.fetch;
|
||||
before(function() {
|
||||
|
||||
+15
-31
@@ -1,14 +1,13 @@
|
||||
"use strict";
|
||||
const events = require("events");
|
||||
const http = require("http");
|
||||
const express = require("express");
|
||||
import events from "node:events";
|
||||
import http from "node:http";
|
||||
import express from "express";
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { User, UserManager, UserRecord, InstanceManager } = require("@clusterio/controller");
|
||||
import * as lib from "@clusterio/lib";
|
||||
import { User, UserManager, UserRecord, InstanceManager } from "@clusterio/controller";
|
||||
|
||||
const addr = lib.Address.fromShorthand;
|
||||
|
||||
class MockLogger {
|
||||
export class MockLogger {
|
||||
child() { return this; }
|
||||
|
||||
fatal() { }
|
||||
@@ -26,7 +25,7 @@ class MockLogger {
|
||||
verbose() { }
|
||||
}
|
||||
|
||||
class MockSocket {
|
||||
export class MockSocket {
|
||||
constructor() {
|
||||
this.sentMessages = [];
|
||||
this.events = new Map();
|
||||
@@ -66,7 +65,7 @@ class MockSocket {
|
||||
}
|
||||
}
|
||||
|
||||
class MockConnector extends lib.BaseConnector {
|
||||
export class MockConnector extends lib.BaseConnector {
|
||||
constructor(src, dst) {
|
||||
super(src, dst);
|
||||
|
||||
@@ -86,7 +85,7 @@ class MockConnector extends lib.BaseConnector {
|
||||
}
|
||||
}
|
||||
|
||||
class MockServer extends events.EventEmitter {
|
||||
export class MockServer extends events.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
this.reset();
|
||||
@@ -116,7 +115,7 @@ class MockServer extends events.EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
class MockInstance extends lib.Link {
|
||||
export class MockInstance extends lib.Link {
|
||||
constructor() {
|
||||
super(new MockConnector(addr({ instanceId: 7357 }), addr({ hostId: 1 })));
|
||||
this.logger = new MockLogger();
|
||||
@@ -144,15 +143,15 @@ class MockInstance extends lib.Link {
|
||||
}
|
||||
}
|
||||
|
||||
class MockHost extends lib.Link {
|
||||
export class MockHost extends lib.Link {
|
||||
constructor() {
|
||||
super(new MockConnector(addr({ hostId: 1 }), addr("controller")));
|
||||
}
|
||||
}
|
||||
|
||||
class MockControl extends lib.Link { }
|
||||
export class MockControl extends lib.Link { }
|
||||
|
||||
class MockController {
|
||||
export class MockController {
|
||||
constructor() {
|
||||
this.app = express();
|
||||
this.app.locals.controller = this;
|
||||
@@ -224,7 +223,7 @@ class MockController {
|
||||
}
|
||||
}
|
||||
|
||||
async function createControllerPlugin(ControllerPluginClass, info) {
|
||||
export async function createControllerPlugin(ControllerPluginClass, info) {
|
||||
let controller = new MockController();
|
||||
let metrics = {};
|
||||
let logger = new MockLogger();
|
||||
@@ -233,25 +232,10 @@ async function createControllerPlugin(ControllerPluginClass, info) {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
async function createInstancePlugin(InstancePluginClass, info) {
|
||||
export async function createInstancePlugin(InstancePluginClass, info) {
|
||||
let instance = new MockInstance();
|
||||
let host = new MockHost();
|
||||
let plugin = new InstancePluginClass(info, instance, host);
|
||||
await plugin.init();
|
||||
return plugin;
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
MockLogger,
|
||||
MockSocket,
|
||||
MockConnector,
|
||||
MockServer,
|
||||
MockInstance,
|
||||
MockHost,
|
||||
MockControl,
|
||||
MockController,
|
||||
|
||||
createControllerPlugin,
|
||||
createInstancePlugin,
|
||||
};
|
||||
Reference in new issue
Block a user