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 });
    });
});