test.deploy/core/converters/index.converter.test.ts
test.deploy/core/converters/index.converter.test.ts is a file in Codebase Testing. 142 lines of code and 0 definitions.
import {
codenameOf,
companionOf,
compareVersions,
dependsOn,
fileOf,
indexUrl,
installedOf,
isCurrent,
serverTarget,
stanzaAt,
stanzasOf,
upstreamOf,
} from "@banes-lab/deploy/core/converters/index.converter.ts";
import { describe, expect, it } from "vitest";
const BROTLI = "libnginx-mod-brotli";
const SOURCE = { base: "https://packages.example.test/ubuntu/", component: "main" };
const INDEX = [
"Package: nginx",
"Version: 1.30.4-1~resolute",
"Depends: libc6 (>= 2.34), zlib1g (>= 1:1.1.4)",
"Provides: httpd, nginx, nginx-r1.30.4",
"Filename: pool/n/nginx_1.30.4-1~resolute_amd64.deb",
"SHA256: aaa",
"Description: high performance web server",
" nginx [engine x] is an HTTP server.",
"",
"Package: nginx",
"Version: 1.30.5-1~resolute",
"Provides: httpd, nginx, nginx-r1.30.5",
"Filename: pool/n/nginx_1.30.5-1~resolute_amd64.deb",
"SHA256: bbb",
"",
"Package: nginx-module-njs",
"Version: 1.30.4+1.0.0-1~resolute",
"Depends: libxml2-16 (>= 2.14.1), nginx-r1.30.4",
"Filename: pool/n/nginx-module-njs_1.30.4+1.0.0-1~resolute_amd64.deb",
"SHA256: ccc",
"",
"Package: nginx-module-njs",
"Version: 1.30.4+1.0.1-1~resolute",
"Depends: libxml2-16 (>= 2.14.1), nginx-r1.30.4",
"Filename: pool/n/nginx-module-njs_1.30.4+1.0.1-1~resolute_amd64.deb",
"SHA256: ddd",
"",
"Package: libnginx-mod-brotli",
"Version: 1.1.0+nginx-1.30.4-1~resolute",
"Depends: libbrotli1 (>= 0.6.0), nginx (= 1.30.4-1~resolute)",
"Filename: pool/l/libnginx-mod-brotli_1.1.0+nginx-1.30.4-1~resolute_amd64.deb",
"SHA256: eee",
"",
"Package: libnginx-mod-brotli",
"Version: 1.1.0+nginx-1.30.5-1~resolute",
"Depends: libbrotli1 (>= 0.6.0), nginx (= 1.30.5-1~resolute)",
"Filename: pool/l/libnginx-mod-brotli_1.1.0+nginx-1.30.5-1~resolute_amd64.deb",
"SHA256: fff",
"",
"Package: certbot-plugin",
"Version: 4.0.0-3",
"Depends: certbot, nginx",
"Filename: pool/c/certbot-plugin_4.0.0-3_all.deb",
"SHA256: ggg",
"",
"Package: broken",
"Version: 1",
"",
].join("\r\n");
const STANZAS = stanzasOf(INDEX, SOURCE);
describe("indexUrl and stanzasOf", () => {
it("addresses a repository's package index and reads each complete stanza from it", () => {
expect(indexUrl(SOURCE, "resolute", "amd64")).toBe(
"https://packages.example.test/ubuntu/dists/resolute/main/binary-amd64/Packages",
);
expect(STANZAS.map((stanza) => stanza.name)).toStrictEqual([
"nginx",
"nginx",
"nginx-module-njs",
"nginx-module-njs",
BROTLI,
BROTLI,
"certbot-plugin",
]);
const [first] = STANZAS;
expect(first?.url).toBe("https://packages.example.test/ubuntu/pool/n/nginx_1.30.4-1~resolute_amd64.deb");
expect(first?.provides).toStrictEqual(["httpd", "nginx", "nginx-r1.30.4"]);
expect(first?.depends.at(0)).toStrictEqual({ exact: null, name: "libc6" });
expect(first === undefined ? "" : fileOf(first)).toBe("nginx_1.30.4-1~resolute_amd64.deb");
});
});
describe("version reading", () => {
it("orders versions by their numbers and splits upstream and codename", () => {
expect(compareVersions("1.30.4+1.0.1-1~resolute", "1.30.4+1.0.0-1~resolute")).toBeGreaterThan(0);
expect(compareVersions("1.30.4-1~noble", "1.30.4-1~resolute")).toBe(0);
expect(upstreamOf("1.1.0+nginx-1.30.4-1~noble")).toBe("1.1.0+nginx-1.30.4");
expect(upstreamOf("1.30.4-1~noble")).toBe("1.30.4");
expect(codenameOf("1.30.4-1~noble")).toBe("noble");
expect(codenameOf("1.30.4")).toBe("");
});
});
describe("serverTarget, companionOf and stanzaAt", () => {
it("pins the server to its declared upstream and picks each module built against that exact build", () => {
const target = serverTarget(STANZAS, "1.30.4");
expect(target?.version).toBe("1.30.4-1~resolute");
expect(serverTarget(STANZAS, "1.29.0")).toBeNull();
if (target === null) {
return;
}
expect(companionOf(STANZAS, "nginx-module-njs", target)?.version).toBe("1.30.4+1.0.1-1~resolute");
expect(companionOf(STANZAS, BROTLI, target)?.version).toBe("1.1.0+nginx-1.30.4-1~resolute");
const newer = stanzaAt(STANZAS, "nginx", "1.30.5-1~resolute");
const brotli = stanzaAt(STANZAS, BROTLI, "1.1.0+nginx-1.30.4-1~resolute");
expect(newer?.sha256).toBe("bbb");
expect(newer === null || brotli === null ? null : dependsOn(brotli, newer)).toBe(false);
expect(newer === null ? null : companionOf(STANZAS, "nginx-module-njs", newer)).toBeNull();
expect(newer === null ? null : companionOf(STANZAS, BROTLI, newer)?.sha256).toBe("fff");
const unpinned = stanzaAt(STANZAS, "certbot-plugin", "4.0.0-3");
expect(unpinned === null ? null : dependsOn(unpinned, target)).toBe(false);
expect(stanzaAt(STANZAS, "nginx", "9")).toBeNull();
});
});
describe("installedOf and isCurrent", () => {
it("counts a package as current only when it is configured at the exact version", () => {
const [target] = STANZAS;
if (target === undefined) {
return;
}
const configured = installedOf(
"nginx",
"Package: nginx\nStatus: install ok installed\nVersion: 1.30.4-1~resolute",
);
const unpacked = installedOf(
"nginx",
"Package: nginx\nStatus: install ok unpacked\nVersion: 1.30.4-1~resolute",
);
const older = installedOf("nginx", "Package: nginx\nStatus: install ok installed\nVersion: 1.30.4-1~noble");
const absent = installedOf("nginx", "");
expect(isCurrent(configured, target)).toBe(true);
expect(isCurrent(unpacked, target)).toBe(false);
expect(isCurrent(older, target)).toBe(false);
expect(absent).toStrictEqual({ configured: false, name: "nginx", version: null });
});
});