mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-11 23:04:52 +09:00
Run integration test instead of unit test
This commit is contained in:
1 parent
14b8b5ac61
commit
174c798d4b
2 files changed
+149
-120
No files matched your search
@@ -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");
|
||||
});
|
||||
});
|
||||
@@ -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");
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user