mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-12 07:04:52 +09:00
130 lines
5.0 KiB
JavaScript
130 lines
5.0 KiB
JavaScript
"use strict";
|
|
const assert = require("assert").strict;
|
|
|
|
const mock = require("../mock");
|
|
const libLink = require("@clusterio/lib/link");
|
|
const libPlugin = require("@clusterio/lib/plugin");
|
|
|
|
|
|
describe("lib/plugin", function() {
|
|
describe("class BaseInstancePlugin", function() {
|
|
let instancePlugin;
|
|
it("should be constructible", async function() {
|
|
instancePlugin = new libPlugin.BaseInstancePlugin({}, new mock.MockInstance(), {});
|
|
await instancePlugin.init();
|
|
});
|
|
it("should define defaults for hooks", async function() {
|
|
await instancePlugin.onMetrics();
|
|
await instancePlugin.onStart();
|
|
await instancePlugin.onStop();
|
|
instancePlugin.onExit();
|
|
await instancePlugin.onOutput({});
|
|
instancePlugin.onMasterConnectionEvent("connect");
|
|
await instancePlugin.onPrepareMasterDisconnect();
|
|
});
|
|
describe("sendRcon", function() {
|
|
it("should send commands out of order", async function() {
|
|
instancePlugin.instance.server.rconCommandResults.set("a", { time: 100, response: "a" });
|
|
instancePlugin.instance.server.rconCommandResults.set("b", { time: 50, response: "b" });
|
|
|
|
let a = instancePlugin.sendRcon("a");
|
|
let b = instancePlugin.sendRcon("b");
|
|
let result = await Promise.race([a, b]);
|
|
assert.equal(result, "b");
|
|
});
|
|
it("should propagate errors", async function() {
|
|
instancePlugin.instance.server.rconCommandResults.set("a", new Error("ref"));
|
|
await assert.rejects(instancePlugin.sendRcon("a"), new Error("ref"));
|
|
});
|
|
});
|
|
describe("sendOrderedRcon", function() {
|
|
it("should send commands in order", async function() {
|
|
instancePlugin.instance.server.rconCommandResults.set("a", { time: 100, response: "a" });
|
|
instancePlugin.instance.server.rconCommandResults.set("b", { time: 50, response: "b" });
|
|
|
|
let a = instancePlugin.sendOrderedRcon("a");
|
|
let b = instancePlugin.sendOrderedRcon("b");
|
|
let result = await Promise.race([a, b]);
|
|
assert.equal(result, "a");
|
|
});
|
|
it("should propagate errors", async function() {
|
|
instancePlugin.instance.server.rconCommandResults.set("a", new Error("ref"));
|
|
await assert.rejects(instancePlugin.sendOrderedRcon("a"), new Error("ref"));
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("class BaseMasterPlugin", function() {
|
|
let masterPlugin;
|
|
it("should be constructible", async function() {
|
|
masterPlugin = new libPlugin.BaseMasterPlugin({}, {}, {}, new mock.MockLogger());
|
|
await masterPlugin.init();
|
|
});
|
|
it("should define defaults for hooks", async function() {
|
|
await masterPlugin.onInstanceStatusChanged({}, "running", "initialized");
|
|
await masterPlugin.onMasterConfigFieldChanged({}, "foo", null);
|
|
await masterPlugin.onInstanceConfigFieldChanged({}, {}, "foo", null);
|
|
await masterPlugin.onMetrics();
|
|
await masterPlugin.onShutdown();
|
|
masterPlugin.onSlaveConnectionEvent({}, "connect");
|
|
await masterPlugin.onPrepareSlaveDisconnect({});
|
|
});
|
|
});
|
|
|
|
describe("attachPluginMessages()", function() {
|
|
let mockLink = new libLink.Link("source", "target", new mock.MockConnector());
|
|
let mockEvent = new libLink.Event({ type: "test:test", links: ["target-source"] });
|
|
it("should accept pluginInfo without messages", function() {
|
|
libPlugin.attachPluginMessages(mockLink, { info: {} });
|
|
});
|
|
it("should attach handler for the given message", function() {
|
|
function mockEventEventHandler() { };
|
|
libPlugin.attachPluginMessages(
|
|
mockLink, { mockEventEventHandler, info: { name: "test", messages: { mockEvent }}}
|
|
);
|
|
assert(mockLink._handlers.get("test:test_event"), "handler was not registered");
|
|
});
|
|
it("should throw if missing handler for the given message", function() {
|
|
assert.throws(
|
|
() => libPlugin.attachPluginMessages(mockLink, { info: { name: "test", messages: { mockEvent }}}),
|
|
new Error("Missing mockEventEventHandler on plugin test for test:test_event on source-target link")
|
|
);
|
|
});
|
|
it("should throw if message starts with the wrong prefix", function() {
|
|
assert.throws(
|
|
() => libPlugin.attachPluginMessages(mockLink, { info: { name: "foo", messages: { mockEvent }}}),
|
|
new Error('Type of mockEvent message must start with "foo:"')
|
|
);
|
|
});
|
|
});
|
|
|
|
describe("invokeHook()", function() {
|
|
let betaTestCalled = false;
|
|
let plugins = new Map([
|
|
["alpha", {
|
|
test: async function() { },
|
|
pass: async function(arg) { return arg; },
|
|
error: async function() { throw new Error("Test"); },
|
|
logger: new mock.MockLogger(),
|
|
}],
|
|
["beta", {
|
|
test: async function() { betaTestCalled = true; },
|
|
pass: async function() { },
|
|
error: async function() { },
|
|
logger: new mock.MockLogger(),
|
|
}],
|
|
]);
|
|
it("should invoke the hook on the plugin", async function() {
|
|
await libPlugin.invokeHook(plugins, "test");
|
|
assert(betaTestCalled, "Hook was not called");
|
|
});
|
|
it("should pass and return args", async function() {
|
|
let result = await libPlugin.invokeHook(plugins, "pass", 1234);
|
|
assert.deepEqual(result, [1234]);
|
|
});
|
|
it("should ignore errors", async function() {
|
|
await libPlugin.invokeHook(plugins, "error");
|
|
});
|
|
});
|
|
});
|