110 lines
3.2 KiB
TypeScript
110 lines
3.2 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import {
|
|
buildContainerConfigurationPlan,
|
|
extractContainerConfiguration,
|
|
} from "../../src/server/services/container-configuration.service.ts";
|
|
|
|
test("extracts editable values from Docker inspect", () => {
|
|
assert.deepEqual(
|
|
extractContainerConfiguration({
|
|
Name: "/web",
|
|
HostConfig: {
|
|
RestartPolicy: { Name: "unless-stopped" },
|
|
NanoCpus: 1_500_000_000,
|
|
Memory: 512 * 1024 * 1024,
|
|
NetworkMode: "app-net",
|
|
},
|
|
NetworkSettings: { Networks: { "app-net": {}, monitoring: {} } },
|
|
}),
|
|
{
|
|
name: "web",
|
|
restartPolicy: "unless-stopped",
|
|
cpuLimit: 1.5,
|
|
memoryLimitMb: 512,
|
|
networks: ["app-net", "monitoring"],
|
|
primaryNetwork: "app-net",
|
|
},
|
|
);
|
|
});
|
|
|
|
test("plans live updates and reports disruptive changes", () => {
|
|
const plan = buildContainerConfigurationPlan({
|
|
current: {
|
|
name: "web",
|
|
restartPolicy: "unless-stopped",
|
|
cpuLimit: 1,
|
|
memoryLimitMb: 256,
|
|
networks: ["app-net"],
|
|
primaryNetwork: "app-net",
|
|
},
|
|
draft: {
|
|
name: "web-v2",
|
|
restartPolicy: "always",
|
|
cpuLimit: 2,
|
|
memoryLimitMb: 512,
|
|
networks: ["app-net", "monitoring"],
|
|
},
|
|
availableNetworks: ["app-net", "monitoring"],
|
|
});
|
|
|
|
assert.equal(plan.strategy, "LIVE_UPDATE");
|
|
assert.equal(plan.requiresDowntime, false);
|
|
assert.deepEqual(plan.addedNetworks, ["monitoring"]);
|
|
assert.deepEqual(plan.removedNetworks, []);
|
|
assert.deepEqual(
|
|
plan.changes.map((change) => change.field),
|
|
["name", "restartPolicy", "cpuLimit", "memoryLimitMb", "networks"],
|
|
);
|
|
assert.ok(plan.warnings.some((warning) => warning.includes("Docker DNS")));
|
|
assert.equal(plan.blockedReasons.length, 0);
|
|
});
|
|
|
|
test("blocks primary network removal and Compose-managed mutation", () => {
|
|
const plan = buildContainerConfigurationPlan({
|
|
current: {
|
|
name: "web",
|
|
restartPolicy: "no",
|
|
cpuLimit: 0,
|
|
memoryLimitMb: 0,
|
|
networks: ["app-net", "monitoring"],
|
|
primaryNetwork: "app-net",
|
|
},
|
|
draft: {
|
|
name: "web",
|
|
restartPolicy: "no",
|
|
cpuLimit: 0,
|
|
memoryLimitMb: 0,
|
|
networks: ["monitoring"],
|
|
},
|
|
availableNetworks: ["app-net", "monitoring"],
|
|
composeManaged: true,
|
|
});
|
|
|
|
assert.ok(plan.blockedReasons.some((reason) => reason.includes("Compose-managed")));
|
|
assert.ok(plan.blockedReasons.some((reason) => reason.includes("Primary network")));
|
|
});
|
|
|
|
test("produces a stable revision independent of network ordering", () => {
|
|
const base = {
|
|
name: "web",
|
|
restartPolicy: "no" as const,
|
|
cpuLimit: 0,
|
|
memoryLimitMb: 0,
|
|
primaryNetwork: "app-net",
|
|
};
|
|
const first = buildContainerConfigurationPlan({
|
|
current: { ...base, networks: ["monitoring", "app-net"] },
|
|
draft: { ...base, networks: ["app-net", "monitoring"] },
|
|
availableNetworks: ["app-net", "monitoring"],
|
|
});
|
|
const second = buildContainerConfigurationPlan({
|
|
current: { ...base, networks: ["app-net", "monitoring"] },
|
|
draft: { ...base, networks: ["monitoring", "app-net"] },
|
|
availableNetworks: ["monitoring", "app-net"],
|
|
});
|
|
|
|
assert.equal(first.expectedConfigRevision, second.expectedConfigRevision);
|
|
assert.equal(first.changes.length, 0);
|
|
});
|