Finish the plugin system integration tests

Adds the last three checks from #342 to test_plugin: an InstanceEcho
request handled on a running instance, a Lua module with a remote
interface that the request calls over RCON, and log tagging checks for
the plugin field and host/instance ids on the controller, host and
instance log lines.

test_plugin now has a module, so the create_scenario and patch unit
tests that relied on it having none use global_chat instead.

Closes #342

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bbassieandClaude Opus 5.5 committed 2026-10-28 22:01:27 +00:00
1 parent 35125a28ab
commit 9ab36151bd
8 files changed
+100 -4

No files matched your search

+57 -1
View File
@@ -17,7 +17,7 @@ import {
} from "./index.js";
import { externalTest, slowTest } from "../common.js";
import { getTestRconPort } from "./rcon_port.js";
import { ControllerEcho, HostEchoReceived } from "../file/test_plugin/messages.js";
import { ControllerEcho, HostEchoReceived, InstanceEcho } from "../file/test_plugin/messages.js";
/** @returns {Promise<Map<number, lib.InstanceDetails>>} */
@@ -1002,6 +1002,62 @@ describe("Integration of Clusterio", function() {
});
});
describe("test_plugin on a running instance", function() {
requiresFactorio(this);
before(async function() {
this.timeout(20000);
if ((await getInstances()).get(44).status !== "running") {
await execCtl("instance start test");
}
});
async function findLog(filter, message) {
// Host and instance logs are forwarded to the controller asynchronously.
for (let attempt = 0; attempt < 100; attempt++) {
const { log } = await getControl().send(
new lib.LogQueryRequest(false, filter.controller ?? false, filter.hostIds ?? [],
filter.instanceIds ?? [], undefined, 100, "desc")
);
const entry = log.find(info => info.message === message);
if (entry) {
return entry;
}
await wait(20);
}
throw new Error(`log entry "${message}" not found`);
}
it("should route a plugin request from control to an instance", async function() {
const response = await getControl().sendTo({ instanceId: 44 }, new InstanceEcho("to-instance"));
assert.equal(response, "to-instance");
});
it("should patch the plugin's Lua module into the save", async function() {
const result = await sendRcon(44, "/sc rcon.print(remote.interfaces.test_plugin.echo)");
assert.equal(result, "true\n");
});
it("should tag plugin log entries with the plugin and where they came from", async function() {
await getControl().sendTo("controller", new ControllerEcho("log-tagging"));
await getControl().sendTo({ instanceId: 44 }, new InstanceEcho("log-tagging"));
const controllerEntry = await findLog({ controller: true }, "test_plugin controller echo log-tagging");
assert.equal(controllerEntry.plugin, "test_plugin");
assert.equal(controllerEntry.host_id, undefined);
assert.equal(controllerEntry.instance_id, undefined);
const hostEntry = await findLog({ hostIds: [4] }, "test_plugin host echo log-tagging");
assert.equal(hostEntry.plugin, "test_plugin");
assert.equal(hostEntry.host_id, 4);
assert.equal(hostEntry.instance_id, undefined);
const instanceEntry = await findLog({ instanceIds: [44] }, "test_plugin instance echo log-tagging");
assert.equal(instanceEntry.plugin, "test_plugin");
assert.equal(instanceEntry.host_id, 4);
assert.equal(instanceEntry.instance_id, 44);
});
});
describe("instance config set-prop", function() {
requiresFactorio(this);
it("applies factorio settings while running", async function() {