Run integration test instead of unit test

This commit is contained in:
Danielv123 committed 2025-08-04 18:46:13 +00:00
1 parent 14b8b5ac61
commit 174c798d4b
2 files changed
+149 -120

No files matched your search

-120
View File
@@ -1,120 +0,0 @@
"use strict";
const assert = require("assert").strict;
const lib = require("@clusterio/lib");
// Import the command registration helper from the compiled Ctl package. This
// gives us access to the full command tree without spinning up a controller or
// host process.
const { registerCommands } = require("@clusterio/ctl/dist/node/src/commands");
// yargs instance used only for command registration (it will not parse any
// command-line input in these tests).
function createYargsStub() {
const stub = {};
for (const method of ["command", "option", "options", "positional"]) {
stub[method] = () => stub;
}
return stub;
}
const yargs = createYargsStub();
/**
* Fetches the requested sub-command from the command tree under the
* "instance" command.
*
* @param {string} name – The name of the sub-command (e.g. "start-all").
* @returns {Promise<object>} The command object.
*/
async function getInstanceSubCommand(name) {
const rootCommands = await registerCommands(new Map(), yargs);
const instanceTree = rootCommands.subCommands.get("instance");
const command = instanceTree.subCommands.get(name);
if (!command) {
throw new Error(`${name} command was not found in command tree`);
}
return command;
}
/**
* Constructs a mock control link implementing the minimal API surface
* required by the *-all commands (send and sendTo).
*
* @param {lib.InstanceDetails[]} instances – List returned by the mocked
* InstanceDetailsListRequest.
* @param {string} action – The property name ("started" | "stopped") that
* should collect the instance ids passed to sendTo.
* @returns {object} The mock control link.
*/
function createMockControl(instances, action) {
return {
// Called by the command to fetch the instance list.
async send(_request) {
return instances;
},
// Populated by sendTo calls performed by the command.
[action]: [],
async sendTo(target, _request) {
this[action].push(target.instanceId);
},
};
}
describe("ctl instance start-all command", function () {
let startAllCommand;
before(async function () {
startAllCommand = await getInstanceSubCommand("start-all");
});
it("starts only stopped instances that are not excluded by default", async function () {
const instances = [
new lib.InstanceDetails("one", 1, undefined, undefined, "stopped", "1.1.0", 0, false),
new lib.InstanceDetails("two", 2, undefined, undefined, "running", "1.1.0", 0, false),
new lib.InstanceDetails("three", 3, undefined, undefined, "stopped", "1.1.0", 0, true),
];
const control = createMockControl(instances, "started");
await startAllCommand.run({ force: false }, control);
assert.deepEqual(control.started, [1], "Should only start non-excluded stopped instances");
});
it("starts excluded instances when --force flag is provided", async function () {
const instances = [
new lib.InstanceDetails("one", 1, undefined, undefined, "stopped", "1.1.0", 0, false),
new lib.InstanceDetails("three", 3, undefined, undefined, "stopped", "1.1.0", 0, true),
];
const control = createMockControl(instances, "started");
await startAllCommand.run({ force: true }, control);
// Order is not guaranteed – sort before comparison.
assert.deepEqual(control.started.sort(), [1, 3], "--force should include excluded instances");
});
});
describe("ctl instance stop-all command", function () {
let stopAllCommand;
before(async function () {
stopAllCommand = await getInstanceSubCommand("stop-all");
});
it("stops only running or starting instances", async function () {
const instances = [
new lib.InstanceDetails("one", 1, undefined, undefined, "stopped", "1.1.0", 0, false),
// Does not care about excludeFromStartAll
new lib.InstanceDetails("two", 2, undefined, undefined, "running", "1.1.0", 0, true),
new lib.InstanceDetails("three", 3, undefined, undefined, "starting", "1.1.0", 0, false),
];
const control = createMockControl(instances, "stopped");
await stopAllCommand.run({}, control);
// Order is not guaranteed – sort before comparison.
assert.deepEqual(control.stopped.sort(), [2, 3], "Should only stop running or starting instances");
});
});
+149
View File
@@ -34,6 +34,8 @@ describe("Clusterio Instance", function() {
await execCtlProcess(`instance config set-prop ${instName} factorio.settings visibility "${visibility}"`);
await execCtl(`instance config set-prop ${instName} factorio.settings require_user_verification false`);
await execCtl(`instance assign ${instName} 4`);
// Exclude main test instance from start-all to prevent interference
await execCtl(`instance config set ${instName} instance.exclude_from_start_all true`);
for (const plugin of [
"global_chat", "research_sync", "statistics_exporter", "subspace_storage", "player_auth", "inventory_sync",
@@ -47,6 +49,8 @@ describe("Clusterio Instance", function() {
await execCtlProcess(`instance config set-prop ${instAltName} factorio.settings visibility "${visibility}"`);
await execCtl(`instance config set-prop ${instAltName} factorio.settings require_user_verification false`);
await execCtl(`instance assign ${instAltName} 4`);
// Exclude alt test instance from start-all to prevent interference
await execCtl(`instance config set ${instAltName} instance.exclude_from_start_all true`);
await execCtl(`instance start ${instAltName}`);
await sendRcon(instAltId, "/sc disable achievements");
});
@@ -162,3 +166,148 @@ describe("Clusterio Instance", function() {
});
}
});
describe("start-all and stop-all commands", function() {
// Test instance IDs for start-all/stop-all tests
const testInstId1 = 50;
const testInstId2 = 51;
const testInstId3 = 52;
const testInstName1 = "StartAllTest1";
const testInstName2 = "StartAllTest2";
const testInstName3 = "StartAllTest3";
before(async function() {
this.timeout(30000);
// Create test instances for start-all/stop-all testing
await execCtl(`instance create ${testInstName1} --id ${testInstId1}`);
await execCtl(`instance create ${testInstName2} --id ${testInstId2}`);
await execCtl(`instance create ${testInstName3} --id ${testInstId3}`);
// Configure instances
await execCtl(`instance assign ${testInstName1} 4`);
await execCtl(`instance assign ${testInstName2} 4`);
await execCtl(`instance assign ${testInstName3} 4`);
// Exclude testInstName3 from start-all by default
await execCtl(`instance config set ${testInstName3} instance.exclude_from_start_all true`);
// Disable plugins to speed up testing
for (const instanceName of [testInstName1, testInstName2, testInstName3]) {
for (const plugin of [
"global_chat", "research_sync", "statistics_exporter",
"subspace_storage", "player_auth", "inventory_sync",
]) {
await execCtl(`instance config set ${instanceName} ${plugin}.load_plugin false`);
}
}
});
after(async function() {
this.timeout(30000);
// Clean up test instances - ensure they are stopped first
await execCtl(`instance stop ${testInstName1}`).catch(() => {});
await execCtl(`instance stop ${testInstName2}`).catch(() => {});
await execCtl(`instance stop ${testInstName3}`).catch(() => {});
await execCtl(`instance delete ${testInstName1}`).catch(() => {});
await execCtl(`instance delete ${testInstName2}`).catch(() => {});
await execCtl(`instance delete ${testInstName3}`).catch(() => {});
});
async function getInstanceStatus(id) {
const instances = await getControl().send(new lib.InstanceDetailsListRequest());
const instanceMap = new Map(instances.map(instance => [instance.id, instance]));
return instanceMap.get(id)?.status;
}
describe("start-all command", function() {
beforeEach(async function() {
this.timeout(15000);
// Ensure all test instances are stopped before each test
await execCtl(`instance stop ${testInstName1}`).catch(() => {});
await execCtl(`instance stop ${testInstName2}`).catch(() => {});
await execCtl(`instance stop ${testInstName3}`).catch(() => {});
});
afterEach(async function() {
this.timeout(15000);
// Clean up: stop any instances that were started during tests
await execCtl(`instance stop ${testInstName1}`).catch(() => {});
await execCtl(`instance stop ${testInstName2}`).catch(() => {});
await execCtl(`instance stop ${testInstName3}`).catch(() => {});
});
it("starts only stopped instances that are not excluded by default", async function() {
this.timeout(20000);
// Start one instance to verify it's not started again
await execCtl(`instance start ${testInstName2}`);
// Verify initial state
assert.equal(await getInstanceStatus(testInstId1), "stopped");
assert.equal(await getInstanceStatus(testInstId2), "running");
assert.equal(await getInstanceStatus(testInstId3), "stopped");
// Run start-all without force
await execCtl("instance start-all");
// Verify results - only testInstName1 should be started
// testInstName2 was already running, testInstName3 is excluded
assert.equal(await getInstanceStatus(testInstId1), "running");
assert.equal(await getInstanceStatus(testInstId2), "running");
assert.equal(await getInstanceStatus(testInstId3), "stopped");
});
it("starts excluded instances when --force flag is provided", async function() {
this.timeout(20000);
// Verify initial state - all stopped
assert.equal(await getInstanceStatus(testInstId1), "stopped");
assert.equal(await getInstanceStatus(testInstId2), "stopped");
assert.equal(await getInstanceStatus(testInstId3), "stopped");
// Run start-all with force
await execCtl("instance start-all --force");
// Verify results - all instances should be started including excluded one
assert.equal(await getInstanceStatus(testInstId1), "running");
assert.equal(await getInstanceStatus(testInstId2), "running");
assert.equal(await getInstanceStatus(testInstId3), "running");
});
});
describe("stop-all command", function() {
beforeEach(async function() {
this.timeout(15000);
// Ensure a known state before each test
await execCtl(`instance stop ${testInstName1}`).catch(() => {});
await execCtl(`instance stop ${testInstName2}`).catch(() => {});
await execCtl(`instance stop ${testInstName3}`).catch(() => {});
});
afterEach(async function() {
this.timeout(15000);
// Clean up: stop any instances that were started during tests
await execCtl(`instance stop ${testInstName1}`).catch(() => {});
await execCtl(`instance stop ${testInstName2}`).catch(() => {});
await execCtl(`instance stop ${testInstName3}`).catch(() => {});
});
it("stops only running or starting instances", async function() {
this.timeout(20000);
// Start some instances to test stop-all
await execCtl(`instance start ${testInstName1}`);
await execCtl(`instance start ${testInstName3}`);
// Verify initial state
assert.equal(await getInstanceStatus(testInstId1), "running");
assert.equal(await getInstanceStatus(testInstId2), "stopped");
assert.equal(await getInstanceStatus(testInstId3), "running");
await execCtl("instance stop-all");
// Verify results - running instances should be stopped, stopped ones unchanged
assert.equal(await getInstanceStatus(testInstId1), "stopped");
assert.equal(await getInstanceStatus(testInstId2), "stopped");
assert.equal(await getInstanceStatus(testInstId3), "stopped");
});
});
});