mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-12 07:04:52 +09:00
Migrate the usage of CommonJS specific code and imports to ESM. Roughly summarised this: - Changes all require() calls to import statement or expressions. - Changes usage of module.exports to export statements. - Replaces require.resolve with import.meta.resolve. - Replaces conditional imports with conditional subpath imports. - Replaces module === require.main with import.meta.main. - Adds the full filename with extention to all relative imports. - Changes all usage of __dirname and __filename to their import.meta equivalents. - Sets "type": "module" in package.json files. - Removes usage of "use strict". - Adds .ts an an alias of .js for the webpack build. Due to differences in how require and import resolves files the plugin entrypoints will have to include the filename and extension after this migration in order to work.
358 lines
10 KiB
JavaScript
358 lines
10 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import * as lib from "@clusterio/lib";
|
|
|
|
import { Controller, InstanceRecord, InstanceManager } from "@clusterio/controller";
|
|
|
|
describe("controller/InstanceManager", function () {
|
|
/** @type {Controller} */
|
|
let controller;
|
|
/** @type {InstanceManager} */
|
|
let instances;
|
|
/** @type {InstanceRecord} */
|
|
let instance;
|
|
|
|
beforeEach(function () {
|
|
const controllerConfig = new lib.ControllerConfig("controller", {
|
|
"controller.name": "TestController",
|
|
});
|
|
const instanceConfig = new lib.InstanceConfig("controller", {
|
|
"instance.id": 1,
|
|
"instance.name": "Test",
|
|
});
|
|
|
|
const datastoreInstances = new lib.SubscribableDatastore();
|
|
datastoreInstances.set(new InstanceRecord(instanceConfig, "unassigned"));
|
|
|
|
controller = new Controller(lib.logger, [], controllerConfig,
|
|
undefined, undefined, undefined, undefined, datastoreInstances);
|
|
instances = controller.instances;
|
|
instance = instances.getMutable(1);
|
|
});
|
|
|
|
describe("constructor()", function () {
|
|
it("should call _notifyConfigFieldChanged when config changes", async function () {
|
|
let called = false;
|
|
|
|
instances._notifyConfigFieldChanged = async (
|
|
inst, field, curr, prev
|
|
) => {
|
|
called = true;
|
|
assert.equal(inst.id, 1);
|
|
assert.equal(field, "instance.name");
|
|
assert.equal(prev, "Test");
|
|
assert.equal(curr, "Updated");
|
|
};
|
|
|
|
instance.config.set("instance.name", "Updated");
|
|
|
|
assert.equal(called, true);
|
|
});
|
|
|
|
it("should update datastore when config changes", function () {
|
|
let setCalled = false;
|
|
|
|
const originalSet = instances.records.set.bind(instances.records);
|
|
instances.records.set = function (value) {
|
|
setCalled = true;
|
|
return originalSet(value);
|
|
};
|
|
|
|
instance.config.set("instance.name", "Changed");
|
|
|
|
assert.equal(setCalled, true);
|
|
});
|
|
});
|
|
|
|
describe(".has() / .get() / .getMutable()", function () {
|
|
it("should return instance when exists", async function () {
|
|
assert.equal(instances.has(instance.id), true);
|
|
assert.equal(instances.get(instance.id), instance);
|
|
assert.equal(instances.getMutable(instance.id), instance);
|
|
});
|
|
|
|
it("should return undefined when missing", function () {
|
|
assert.equal(instances.has(999), false);
|
|
assert.equal(instances.get(999), undefined);
|
|
});
|
|
});
|
|
|
|
describe(".values() / .valuesMutable()", function () {
|
|
it("should iterate all instances", async function () {
|
|
const config1 = new lib.InstanceConfig("controller", {
|
|
"instance.id": 2,
|
|
"instance.name": "A",
|
|
});
|
|
const config2 = new lib.InstanceConfig("controller", {
|
|
"instance.id": 3,
|
|
"instance.name": "B",
|
|
});
|
|
|
|
const i1 = await instances.createInstance(config1);
|
|
const i2 = await instances.createInstance(config2);
|
|
|
|
assert.deepEqual(Array.from(instances.values()), [instance, i1, i2]);
|
|
assert.deepEqual(Array.from(instances.valuesMutable()), [instance, i1, i2]);
|
|
});
|
|
});
|
|
|
|
describe(".getForRequest()", function () {
|
|
it("should return instance when exists", async function () {
|
|
assert.equal(instances.getForRequest(1), instance);
|
|
});
|
|
|
|
it("should throw when missing", function () {
|
|
assert.throws(() => instances.getForRequest(999), lib.RequestError);
|
|
});
|
|
});
|
|
|
|
describe(".createInstance()", function () {
|
|
it("should create new instance with id 2", async function () {
|
|
let notified = false;
|
|
instances._notifyStatusChanged = async () => { notified = true; };
|
|
|
|
const config = new lib.InstanceConfig("controller", {
|
|
"instance.id": 2,
|
|
"instance.name": "Second",
|
|
});
|
|
|
|
const created = await instances.createInstance(config);
|
|
|
|
assert.equal(created.id, 2);
|
|
assert(instances.get(2), created);
|
|
assert.equal(notified, true);
|
|
});
|
|
|
|
it("should call notify on config change", async function () {
|
|
let notified = false;
|
|
instances._notifyConfigFieldChanged = async () => { notified = true; };
|
|
|
|
const config = new lib.InstanceConfig("controller", {
|
|
"instance.id": 2,
|
|
"instance.name": "Second",
|
|
});
|
|
|
|
const created = await instances.createInstance(config);
|
|
|
|
created.config.set("instance.name", "Updated");
|
|
|
|
assert.equal(created.id, 2);
|
|
assert.equal(instances.get(2), created);
|
|
assert.equal(notified, true);
|
|
});
|
|
|
|
it("should throw if id already exists", async function () {
|
|
const config = new lib.InstanceConfig("controller", {
|
|
"instance.id": 1,
|
|
"instance.name": "Duplicate",
|
|
});
|
|
|
|
await assert.rejects(
|
|
() => instances.createInstance(config),
|
|
lib.RequestError
|
|
);
|
|
});
|
|
|
|
it("should suppress changes when flag set", async function () {
|
|
let notified = false;
|
|
instances._notifyStatusChanged = async () => { notified = true; };
|
|
|
|
const config = new lib.InstanceConfig("controller", {
|
|
"instance.id": 2,
|
|
"instance.name": "Suppressed",
|
|
});
|
|
|
|
const created = await instances.createInstance(config, true);
|
|
|
|
assert.equal(instances.get(2), undefined);
|
|
assert.equal(notified, false);
|
|
});
|
|
});
|
|
|
|
describe(".assignInstance()", function () {
|
|
it("should throw if host not connected", async function () {
|
|
await assert.rejects(
|
|
() => instances.assignInstance(1, 5),
|
|
lib.RequestError
|
|
);
|
|
});
|
|
|
|
it("should do nothing if the host would not change", async function () {
|
|
let assignRequest;
|
|
controller.wsServer.hostConnections.set(5, {
|
|
send: async (request) => {
|
|
assignRequest = request;
|
|
},
|
|
connector: { closing: false },
|
|
});
|
|
|
|
instance.config.set("instance.assigned_host", 5);
|
|
|
|
await instances.assignInstance(1, 5);
|
|
assert.equal(assignRequest, undefined);
|
|
});
|
|
|
|
it("should not unassign if new host is not connected", async function () {
|
|
let unassignRequest;
|
|
controller.wsServer.hostConnections.set(5, {
|
|
send: async (request) => {
|
|
unassignRequest = request;
|
|
},
|
|
connector: { closing: false },
|
|
});
|
|
|
|
instance.config.set("instance.assigned_host", 5);
|
|
|
|
await assert.rejects(
|
|
() => instances.assignInstance(1, 6),
|
|
lib.RequestError
|
|
);
|
|
|
|
assert.equal(unassignRequest, undefined);
|
|
});
|
|
|
|
it("should assign to connected host", async function () {
|
|
let assignRequest;
|
|
controller.wsServer.hostConnections.set(5, {
|
|
send: async (request) => {
|
|
assignRequest = request;
|
|
},
|
|
connector: { closing: false },
|
|
});
|
|
|
|
await instances.assignInstance(1, 5);
|
|
|
|
assert.equal(instance.config.get("instance.assigned_host"), 5);
|
|
assert(assignRequest instanceof lib.InstanceAssignInternalRequest);
|
|
assert.equal(assignRequest.instanceId, 1);
|
|
});
|
|
|
|
it("should not fail when host has id of 0", async function () {
|
|
let lastEvent;
|
|
controller.wsServer.hostConnections.set(0, {
|
|
send: async (request) => {
|
|
lastEvent = request;
|
|
},
|
|
connector: { closing: false },
|
|
});
|
|
|
|
await instances.assignInstance(1, 0);
|
|
|
|
assert.equal(instance.config.get("instance.assigned_host"), 0);
|
|
assert(lastEvent instanceof lib.InstanceAssignInternalRequest);
|
|
assert.equal(lastEvent.instanceId, 1);
|
|
|
|
await instances.assignInstance(1, null);
|
|
|
|
assert.equal(instance.config.get("instance.assigned_host"), null);
|
|
assert(lastEvent instanceof lib.InstanceUnassignInternalRequest);
|
|
assert.equal(lastEvent.instanceId, 1);
|
|
});
|
|
|
|
it("should unassign old host if connected", async function () {
|
|
let unassignRequest;
|
|
controller.wsServer.hostConnections.set(5, {
|
|
send: async (request) => {
|
|
unassignRequest = request;
|
|
},
|
|
connector: { closing: false },
|
|
});
|
|
|
|
let assignRequest;
|
|
controller.wsServer.hostConnections.set(6, {
|
|
send: async (request) => {
|
|
assignRequest = request;
|
|
},
|
|
connector: { closing: false },
|
|
});
|
|
|
|
instance.config.set("instance.assigned_host", 5);
|
|
await instances.assignInstance(1, 6);
|
|
|
|
assert(unassignRequest instanceof lib.InstanceUnassignInternalRequest);
|
|
assert.equal(unassignRequest.instanceId, 1);
|
|
assert(assignRequest instanceof lib.InstanceAssignInternalRequest);
|
|
assert.equal(assignRequest.instanceId, 1);
|
|
});
|
|
|
|
it("should not unassign if old host closing", async function () {
|
|
let unassignRequest;
|
|
controller.wsServer.hostConnections.set(5, {
|
|
send: async (request) => {
|
|
unassignRequest = request;
|
|
},
|
|
connector: { closing: true },
|
|
});
|
|
|
|
let assignRequest;
|
|
controller.wsServer.hostConnections.set(6, {
|
|
send: async (request) => {
|
|
assignRequest = request;
|
|
},
|
|
connector: { closing: false },
|
|
});
|
|
|
|
instance.config.set("instance.assigned_host", 5);
|
|
await instances.assignInstance(1, 6);
|
|
|
|
assert.equal(unassignRequest, undefined);
|
|
assert(assignRequest instanceof lib.InstanceAssignInternalRequest);
|
|
assert.equal(assignRequest.instanceId, 1);
|
|
});
|
|
});
|
|
|
|
describe(".unassignInstance()", function () {
|
|
it("should unassign an instance", async function () {
|
|
controller.wsServer.hostConnections.set(5, {
|
|
send: async () => {},
|
|
connector: { closing: true },
|
|
});
|
|
|
|
await instances.assignInstance(instance.id, 5);
|
|
await instances.unassignInstance(instance.id);
|
|
assert.equal(instance.config.get("instance.assigned_host"), null);
|
|
assert.equal(instance.status, "unassigned");
|
|
});
|
|
it("should do nothing if the host would not change", async function () {
|
|
instance.config.set("instance.assigned_host", null);
|
|
|
|
let fieldChanged;
|
|
instance.config.on("fieldChanged", name => {
|
|
fieldChanged = name;
|
|
});
|
|
|
|
await instances.unassignInstance(1);
|
|
assert.equal(fieldChanged, undefined);
|
|
});
|
|
});
|
|
|
|
describe(".deleteInstance()", function () {
|
|
it("should delete and notify", async function () {
|
|
let notified = false;
|
|
instances._notifyStatusChanged = async () => { notified = true; };
|
|
|
|
await instances.deleteInstance(1);
|
|
|
|
assert.equal(instances.get(1), undefined);
|
|
assert.equal(notified, true);
|
|
});
|
|
|
|
it("should send delete to host if assigned", async function () {
|
|
let sentRequest;
|
|
controller.sendTo = async (_target, request) => {
|
|
sentRequest = request;
|
|
};
|
|
|
|
controller.wsServer.hostConnections.set(5, {
|
|
send: async () => {},
|
|
connector: { closing: false },
|
|
});
|
|
|
|
await instances.assignInstance(1, 5);
|
|
await instances.deleteInstance(1);
|
|
|
|
assert(sentRequest instanceof lib.InstanceDeleteInternalRequest);
|
|
assert.equal(sentRequest.instanceId, 1);
|
|
});
|
|
});
|
|
});
|