diff --git a/src/docker-build-cache.test.ts b/src/docker-build-cache.test.ts index 434751341d2..65b59ab0342 100644 --- a/src/docker-build-cache.test.ts +++ b/src/docker-build-cache.test.ts @@ -1,12 +1,39 @@ import { readFile } from "node:fs/promises"; import { resolve } from "node:path"; import { fileURLToPath } from "node:url"; -import { describe, expect, it } from "vitest"; +import { beforeAll, describe, expect, it } from "vitest"; const repoRoot = resolve(fileURLToPath(new URL(".", import.meta.url)), ".."); +const dockerfilePaths = [ + "Dockerfile", + "Dockerfile.sandbox", + "Dockerfile.sandbox-browser", + "Dockerfile.sandbox-common", + "scripts/docker/cleanup-smoke/Dockerfile", + "scripts/docker/install-sh-smoke/Dockerfile", + "scripts/docker/install-sh-e2e/Dockerfile", + "scripts/docker/install-sh-nonroot/Dockerfile", + "scripts/e2e/Dockerfile", + "scripts/e2e/Dockerfile.qr-import", +] as const; +const aptCacheDockerfilePaths = dockerfilePaths.filter( + (path) => path !== "scripts/e2e/Dockerfile.qr-import" && path !== "scripts/e2e/Dockerfile", +); +const shellContinuationDockerfilePaths = dockerfilePaths.filter( + (path) => + path !== "Dockerfile" && + path !== "scripts/e2e/Dockerfile" && + path !== "scripts/e2e/Dockerfile.qr-import", +); +const repoFileCache = new Map>(); async function readRepoFile(path: string): Promise { - return readFile(resolve(repoRoot, path), "utf8"); + let cached = repoFileCache.get(path); + if (!cached) { + cached = readFile(resolve(repoRoot, path), "utf8"); + repoFileCache.set(path, cached); + } + return cached; } function indexOfPattern(source: string, pattern: RegExp): number { @@ -14,6 +41,10 @@ function indexOfPattern(source: string, pattern: RegExp): number { } describe("docker build cache layout", () => { + beforeAll(async () => { + await Promise.all(dockerfilePaths.map((path) => readRepoFile(path))); + }); + it("keeps the root dependency layer independent from scripts changes", async () => { const dockerfile = await readRepoFile("Dockerfile"); const installIndex = dockerfile.indexOf("pnpm install --frozen-lockfile"); @@ -42,16 +73,7 @@ describe("docker build cache layout", () => { }); it("uses apt cache mounts in Dockerfiles that install system packages", async () => { - for (const path of [ - "Dockerfile", - "Dockerfile.sandbox", - "Dockerfile.sandbox-browser", - "Dockerfile.sandbox-common", - "scripts/docker/cleanup-smoke/Dockerfile", - "scripts/docker/install-sh-smoke/Dockerfile", - "scripts/docker/install-sh-e2e/Dockerfile", - "scripts/docker/install-sh-nonroot/Dockerfile", - ]) { + for (const path of aptCacheDockerfilePaths) { const dockerfile = await readRepoFile(path); expect(dockerfile, `${path} should cache apt package archives`).toContain( "target=/var/cache/apt,sharing=locked", @@ -71,15 +93,7 @@ describe("docker build cache layout", () => { }); it("does not leave blank lines after shell continuation markers", async () => { - for (const path of [ - "Dockerfile.sandbox", - "Dockerfile.sandbox-browser", - "Dockerfile.sandbox-common", - "scripts/docker/cleanup-smoke/Dockerfile", - "scripts/docker/install-sh-smoke/Dockerfile", - "scripts/docker/install-sh-e2e/Dockerfile", - "scripts/docker/install-sh-nonroot/Dockerfile", - ]) { + for (const path of shellContinuationDockerfilePaths) { const dockerfile = await readRepoFile(path); expect( dockerfile,