mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-11 15:04:52 +09:00
Add missing migrations for system info and tests (#766)
* Add missing migration for SystemInfo * Add missing migration tests
This commit is contained in:
1 parent
6e01ba18c5
commit
63e30dd0ee
6 files changed
+149
-9
No files matched your search
@@ -5,6 +5,7 @@ export { default as ControllerRouter } from "./src/ControllerRouter";
|
||||
export { default as ControlConnection } from "./src/ControlConnection";
|
||||
export { default as HostConnection } from "./src/HostConnection";
|
||||
export { default as InstanceInfo } from "./src/InstanceInfo";
|
||||
export { default as HostInfo } from "./src/HostInfo";
|
||||
export { default as BaseControllerPlugin } from "./src/BaseControllerPlugin";
|
||||
export { default as UserManager } from "./src/UserManager";
|
||||
export { default as WsServer } from "./src/WsServer";
|
||||
|
||||
@@ -104,7 +104,8 @@ export default class Controller {
|
||||
|
||||
const systems = new lib.SubscribableDatastore(...await new lib.JsonIdDatastoreProvider(
|
||||
path.join(databaseDirectory, "systems.json"),
|
||||
lib.SystemInfo.fromJSON.bind(lib.SystemInfo)
|
||||
lib.SystemInfo.fromJSON.bind(lib.SystemInfo),
|
||||
this.migrateSystems,
|
||||
).bootstrap());
|
||||
|
||||
const hosts = new lib.SubscribableDatastore(...await new lib.JsonIdDatastoreProvider(
|
||||
@@ -597,10 +598,23 @@ export default class Controller {
|
||||
await lib.invokeHook(this.plugins, "onSaveData");
|
||||
}
|
||||
|
||||
static migrateSystems(rawJson: unknown[]): Static<typeof lib.SystemInfo.jsonSchema>[] {
|
||||
const serialized = rawJson as Static<typeof lib.SystemInfo.jsonSchema>[];
|
||||
return serialized.map(json => {
|
||||
if (!json.canRestart) { // Added in 2.0.0.alpha.17
|
||||
json.canRestart = false;
|
||||
}
|
||||
if (!json.restartRequired) { // Added in 2.0.0.alpha.21
|
||||
json.restartRequired = false;
|
||||
}
|
||||
return json;
|
||||
});
|
||||
}
|
||||
|
||||
static migrateHosts(rawJson: unknown[]): Static<typeof HostInfo.jsonSchema>[] {
|
||||
let serialized = rawJson as any;
|
||||
|
||||
// migrate from pre alpha.19 format
|
||||
// New format 2.0.0.alpha.19
|
||||
if (serialized.length && serialized[0] instanceof Array) {
|
||||
serialized = serialized.map((e: any) => e[1]);
|
||||
}
|
||||
@@ -619,7 +633,7 @@ export default class Controller {
|
||||
static migrateInstances(rawJson: unknown[]): Static<typeof InstanceInfo.jsonSchema>[] {
|
||||
const serialized = rawJson as Static<typeof InstanceInfo.jsonSchema>[];
|
||||
return serialized.map(json => {
|
||||
if (!json.config) { // migrate: from pre Alpha 14 format.
|
||||
if (!json.config) { // New format 2.0.0.alpha.14
|
||||
return { config: json as any, status: "running" }; // Use running to force updatedAtMs
|
||||
}
|
||||
return json;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use strict";
|
||||
const assert = require("assert").strict;
|
||||
const { Controller } = require("@clusterio/controller");
|
||||
const { ControllerConfig, Address, RequestError } = require("@clusterio/lib");
|
||||
const { Controller, HostInfo, InstanceInfo } = require("@clusterio/controller");
|
||||
const { ControllerConfig, Address, RequestError, InstanceConfig, HostConfig, SystemInfo } = require("@clusterio/lib");
|
||||
const { EventEmitter } = require("stream");
|
||||
|
||||
class MockEvent {}
|
||||
@@ -189,5 +189,130 @@ describe("controller/src/Controller", function() {
|
||||
assert(controller.instances.dirty === true, "dirty flag was not set");
|
||||
});
|
||||
});
|
||||
describe(".finaliseHosts()", function() {
|
||||
it("resets the connected state to false", function() {
|
||||
const hostInfo = new HostInfo(1, "", "", new Map(), true);
|
||||
Controller.finaliseHosts(hostInfo);
|
||||
assert.equal(hostInfo.connected, false);
|
||||
assert(hostInfo.updatedAtMs > 0, "updatedAtMs not incremented");
|
||||
});
|
||||
it("does not increment updatedAtMs when there are no changes", function() {
|
||||
const hostInfo = new HostInfo(1, "", "", new Map(), false);
|
||||
Controller.finaliseHosts(hostInfo);
|
||||
assert.equal(hostInfo.connected, false);
|
||||
assert(hostInfo.updatedAtMs === 0, "updatedAtMs incremented");
|
||||
});
|
||||
});
|
||||
describe(".finaliseInstances()", function() {
|
||||
it("resets the stats for assigned instances", function() {
|
||||
const instanceConfig = new InstanceConfig("controller", { "instance.assigned_host": 1 });
|
||||
const instanceInfo = new InstanceInfo(instanceConfig, "running");
|
||||
Controller.finaliseInstances(instanceInfo);
|
||||
assert.equal(instanceInfo.status, "unknown");
|
||||
assert(instanceInfo.updatedAtMs > 0, "updatedAtMs not incremented");
|
||||
});
|
||||
it("resets the status for unassigned instances", function() {
|
||||
const instanceConfig = new InstanceConfig("controller", { "instance.assigned_host": null });
|
||||
const instanceInfo = new InstanceInfo(instanceConfig, "running");
|
||||
Controller.finaliseInstances(instanceInfo);
|
||||
assert.equal(instanceInfo.status, "unassigned");
|
||||
assert(instanceInfo.updatedAtMs > 0, "updatedAtMs not incremented");
|
||||
});
|
||||
it("does not update updatedAtMs when there are no changes (assigned)", function() {
|
||||
const instanceConfig = new InstanceConfig("controller", { "instance.assigned_host": 1 });
|
||||
const instanceInfo = new InstanceInfo(instanceConfig, "unknown");
|
||||
Controller.finaliseInstances(instanceInfo);
|
||||
assert.equal(instanceInfo.status, "unknown");
|
||||
assert(instanceInfo.updatedAtMs === 0, "updatedAtMs incremented");
|
||||
});
|
||||
it("does not update updatedAtMs when there are no changes (unassigned)", function() {
|
||||
const instanceConfig = new InstanceConfig("controller", { "instance.assigned_host": null });
|
||||
const instanceInfo = new InstanceInfo(instanceConfig, "unassigned");
|
||||
Controller.finaliseInstances(instanceInfo);
|
||||
assert.equal(instanceInfo.status, "unassigned");
|
||||
assert(instanceInfo.updatedAtMs === 0, "updatedAtMs incremented");
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("migrations", function() {
|
||||
describe("SystemInfo", function() {
|
||||
it("migrates 'canRestart' from undefined to false", function() { // Alpha 17
|
||||
const result = Controller.migrateSystems([
|
||||
{}, { canRestart: true }, { canRestart: false },
|
||||
]);
|
||||
assert.equal(result[0].canRestart, false);
|
||||
assert.equal(result[1].canRestart, true);
|
||||
assert.equal(result[2].canRestart, false);
|
||||
});
|
||||
it("migrates 'restartRequired' from undefined to false", function() { // Alpha 21
|
||||
const result = Controller.migrateSystems([
|
||||
{}, { restartRequired: true }, { restartRequired: false },
|
||||
]);
|
||||
assert.equal(result[0].restartRequired, false);
|
||||
assert.equal(result[1].restartRequired, true);
|
||||
assert.equal(result[2].restartRequired, false);
|
||||
});
|
||||
it("does nothing for upto date data", function() {
|
||||
const systemInfo = new SystemInfo(
|
||||
1, "name", "n", "k", "m", "cm", "cr", "mc", "ma", "dc", "da", false, false, 0, false
|
||||
);
|
||||
const jsonString = JSON.stringify(systemInfo);
|
||||
const systemInfoJson = JSON.parse(jsonString);
|
||||
const systemInfoJsonCopy = JSON.parse(jsonString);
|
||||
const result = Controller.migrateSystems([
|
||||
systemInfoJson, systemInfoJson, systemInfoJson,
|
||||
]);
|
||||
assert.deepEqual(result, [
|
||||
systemInfoJsonCopy, systemInfoJsonCopy, systemInfoJsonCopy,
|
||||
]);
|
||||
});
|
||||
});
|
||||
describe("HostInfo", function() {
|
||||
it("migrates to the new format", function() { // Alpha 19
|
||||
const result = Controller.migrateHosts([
|
||||
["", "foo"], ["", "bar"], ["", "baz"],
|
||||
]);
|
||||
assert.deepEqual(result, [
|
||||
"foo", "bar", "baz",
|
||||
]);
|
||||
});
|
||||
it("does nothing for upto date data", function() {
|
||||
const hostInfo = new HostInfo(1, "", "", new Map());
|
||||
const jsonString = JSON.stringify(hostInfo);
|
||||
const hostInfoJson = JSON.parse(jsonString);
|
||||
const hostInfoJsonCopy = JSON.parse(jsonString);
|
||||
const result = Controller.migrateHosts([
|
||||
hostInfoJson, hostInfoJson, hostInfoJson,
|
||||
]);
|
||||
assert.deepEqual(result, [
|
||||
hostInfoJsonCopy, hostInfoJsonCopy, hostInfoJsonCopy,
|
||||
]);
|
||||
});
|
||||
});
|
||||
describe("InstanceInfo", function() {
|
||||
it("migrates to the new format", function() { // Alpha 14
|
||||
const result = Controller.migrateInstances([
|
||||
{ name: "foo" }, { name: "bar" }, { name: "baz" },
|
||||
]);
|
||||
assert.deepEqual(result, [
|
||||
{ config: { name: "foo" }, status: "running" },
|
||||
{ config: { name: "bar" }, status: "running" },
|
||||
{ config: { name: "baz" }, status: "running" },
|
||||
]);
|
||||
});
|
||||
it("does nothing for upto date data", function() {
|
||||
const instanceConfig = new InstanceConfig("controller");
|
||||
const instanceInfo = new InstanceInfo(instanceConfig, "unknown");
|
||||
const jsonString = JSON.stringify(instanceInfo);
|
||||
const instanceInfoJson = JSON.parse(jsonString);
|
||||
const instanceInfoJsonCopy = JSON.parse(jsonString);
|
||||
const result = Controller.migrateInstances([
|
||||
instanceInfoJson, instanceInfoJson, instanceInfoJson,
|
||||
]);
|
||||
assert.deepEqual(result, [
|
||||
instanceInfoJsonCopy, instanceInfoJsonCopy, instanceInfoJsonCopy,
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -16,7 +16,7 @@ describe("messages/controller", function() {
|
||||
lib.Address.fromShorthand("controller"),
|
||||
lib.Address.fromShorthand({ controlId: 1 }),
|
||||
);
|
||||
controller = new Controller(lib.logger, [], "", controllerConfig);
|
||||
controller = new Controller(lib.logger, [], controllerConfig);
|
||||
const user = new ControllerUser(controller.userManager, undefined, "test");
|
||||
controlConnection = new ControlConnection({ version: "2.0.0" }, connection, controller, user, 1);
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ describe("messages/controller", function() {
|
||||
lib.Address.fromShorthand({ hostId: 1 }),
|
||||
lib.Address.fromShorthand("controller"),
|
||||
);
|
||||
host = new Host(hostConnector, "", hostConfig, undefined, []);
|
||||
host = new Host(hostConnector, hostConfig, undefined, []);
|
||||
});
|
||||
|
||||
describe("HostUpdateRequest", function() {
|
||||
|
||||
@@ -19,7 +19,7 @@ describe("messages/plugin", function() {
|
||||
lib.Address.fromShorthand("controller"),
|
||||
lib.Address.fromShorthand({ controlId: 1 }),
|
||||
);
|
||||
controller = new Controller(lib.logger, [], "", controllerConfig);
|
||||
controller = new Controller(lib.logger, [], controllerConfig);
|
||||
const user = new ControllerUser(controller.userManager, undefined, "test");
|
||||
controlConnection = new ControlConnection({ version: "2.0.0" }, connection, controller, user, 1);
|
||||
|
||||
@@ -28,7 +28,7 @@ describe("messages/plugin", function() {
|
||||
lib.Address.fromShorthand({ hostId: 1 }),
|
||||
lib.Address.fromShorthand("controller"),
|
||||
);
|
||||
host = new Host(hostConnector, "", hostConfig, undefined, []);
|
||||
host = new Host(hostConnector, hostConfig, undefined, []);
|
||||
});
|
||||
|
||||
describe("PluginDetails", function() {
|
||||
|
||||
Reference in new issue
Block a user