Skip to content

Commit

Permalink
fix: tool-cache does not work (#533)
Browse files Browse the repository at this point in the history
The tool-cache package does not work for the Chromium version. It works
only for the server format. The chrome has a four-part version like
`120.0.6099.109`, and the tool-cache does not retrieve the cached
version. This pull request replaces the standard tool-cache package with
the cache that supports the chrome version format, four-part, release
channel name, snapshot number, and `latest`.

Close #504
  • Loading branch information
ueokande committed May 3, 2024
1 parent 20e34f7 commit e88eaf7
Show file tree
Hide file tree
Showing 12 changed files with 596 additions and 303 deletions.
146 changes: 146 additions & 0 deletions __test__/cache.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import { cacheDir, find } from "../src/cache";
import * as fs from "fs";
import * as os from "os";
import * as path from "path";

const mkdir = (dir: string) => fs.promises.mkdir(dir, { recursive: true });
const touch = (file: string) => fs.promises.writeFile(file, "");
const expectDir = async (dir: string) =>
expect((await fs.promises.stat(dir)).isDirectory()).toBeTruthy();
const expectFile = async (file: string) =>
expect((await fs.promises.stat(file)).isFile()).toBeTruthy();

describe("find", () => {
let tempToolCacheDir: string;
beforeEach(async () => {
tempToolCacheDir = await fs.promises.mkdtemp(
path.join(os.tmpdir(), "setup-chrome-"),
);
process.env.RUNNER_TOOL_CACHE = tempToolCacheDir;
});

afterEach(async () => {
await fs.promises.rm(tempToolCacheDir, { recursive: true });
});

describe("when several versions are cached", () => {
beforeEach(async () => {
const caches = [
["100.0.1.0", "x64"],
["100.1.0.0", "x64"],
["100.1.1.0", "x64"],
["100.2.0.0", "x64"],
["latest", "x64"],
["canary", "x64"],
["123456", "x64"],
["200000", "x64"],
["300000", "arm64"],
];
for (const [version, arch] of caches) {
const dir = path.join(
tempToolCacheDir,
"setup-chrome",
"chrome",
version,
arch,
);
await mkdir(dir);
await touch(`${dir}.complete`);
}
});

test.each`
version | arch | subdir
${"100.0.1.0"} | ${"x64"} | ${"100.0.1.0/x64"}
${"100.1"} | ${"x64"} | ${"100.1.1.0/x64"}
${"100"} | ${"x64"} | ${"100.2.0.0/x64"}
${"latest"} | ${"x64"} | ${"latest/x64"}
${"canary"} | ${"x64"} | ${"canary/x64"}
${"123456"} | ${"x64"} | ${"123456/x64"}
${"300000"} | ${"arm64"} | ${"300000/arm64"}
${"200"} | ${"x64"} | ${undefined}
${"stable"} | ${"x64"} | ${undefined}
`("finds a tool in the cache", async ({ version, arch, subdir }) => {
expect(await find("chrome", version, arch)).toBe(
subdir && path.join(tempToolCacheDir, "setup-chrome", "chrome", subdir),
);
});
});

describe("when cache is empty", () => {
test("cache is not found", async () => {
expect(await find("chrome", "100", "x64")).toBeUndefined();
});
});

describe("when cache includes corrupted cache", () => {
beforeEach(async () => {
const dir = path.join(tempToolCacheDir, "setup-chrome", "chrome");
await mkdir(path.join(dir, "100.0.0.0", "x64"));
await mkdir(path.join(dir, "100.0.0.0", "x64") + ".complete");
await mkdir(path.join(dir, "100.1.0.0", "x64"));
await mkdir(path.join(dir, "100.1.0.0", "x64") + ".complete");
await mkdir(path.join(dir, "100.2.0.0", "x64"));
});

test("cache is not found", async () => {
expect(await find("chrome", "100.2.0.0", "x64")).toBeUndefined();
});

test("corrupted cache is ignored", async () => {
expect(await find("chrome", "100", "x64")).toBe(
path.join(
tempToolCacheDir,
"setup-chrome",
"chrome",
"100.1.0.0",
"x64",
),
);
});
});
});

describe("cacheDir", () => {
let tempToolCacheDir: string;
let workspaceDir: string;
beforeEach(async () => {
tempToolCacheDir = await fs.promises.mkdtemp(
path.join(os.tmpdir(), "setup-chrome-"),
);
workspaceDir = await fs.promises.mkdtemp(
path.join(os.tmpdir(), "setup-chrome-"),
);
process.env.RUNNER_TOOL_CACHE = tempToolCacheDir;
});

afterEach(async () => {
await fs.promises.rm(workspaceDir, { recursive: true });
await fs.promises.rm(tempToolCacheDir, { recursive: true });
});

test("saves a tool in the cache", async () => {
const caches = [
["100.0.0.0", "x64"],
["100.1.0.0", "arm64"],
["latest", "x64"],
];
for (const [version, arch] of caches) {
const src = path.join(workspaceDir, version);
await mkdir(src);
await touch(path.join(src, "file"));

await cacheDir(src, "chrome", version, arch);
}

const prefix = path.join(tempToolCacheDir, "setup-chrome", "chrome");
await expectDir(path.join(prefix, "100.0.0.0", "x64"));
await expectFile(path.join(prefix, "100.0.0.0", "x64", "file"));
await expectFile(path.join(prefix, "100.0.0.0", "x64") + ".complete");
await expectDir(path.join(prefix, "100.1.0.0", "arm64"));
await expectFile(path.join(prefix, "100.1.0.0", "arm64", "file"));
await expectFile(path.join(prefix, "100.1.0.0", "arm64") + ".complete");
await expectDir(path.join(prefix, "latest", "x64"));
await expectFile(path.join(prefix, "latest", "x64", "file"));
});
});
191 changes: 78 additions & 113 deletions __test__/version.test.ts
Original file line number Diff line number Diff line change
@@ -1,141 +1,106 @@
import { StaticVersion, VersionSpec } from "../src/version";
import { parse, isReleaseChannelName } from "../src/version";

describe("StaticVersion", () => {
describe("constructor", () => {
test("new instance", () => {
const version = new StaticVersion({
major: 119,
minor: 0,
build: 6045,
patch: 123,
});

expect(version.major).toBe(119);
expect(version.minor).toBe(0);
expect(version.build).toBe(6045);
expect(version.patch).toBe(123);
});

test("parse", () => {
const version = new StaticVersion("119.0.6045.123");

expect([
version.major,
version.minor,
version.build,
version.patch,
]).toEqual([119, 0, 6045, 123]);
});

test.each([
["119.0.6045.123.456"],
["119.0.6045.-123"],
["119.0.6045.beta"],
["119.0.6045"],
])("throw an error for %s", (version) => {
expect(() => new StaticVersion(version)).toThrow(
`Invalid version: ${version}`,
);
});
describe("isReleaseChannelName", () => {
test("return true if the version is a release channel name", () => {
expect(isReleaseChannelName("stable")).toBe(true);
expect(isReleaseChannelName("beta")).toBe(true);
expect(isReleaseChannelName("dev")).toBe(true);
expect(isReleaseChannelName("canary")).toBe(true);
expect(isReleaseChannelName("latest")).toBe(false);
expect(isReleaseChannelName("unknown")).toBe(false);
});
});

describe("compare", () => {
test.each`
a | b | equals | greaterThan | lessThan | greaterThanOrEqual | lessThanOrEqual
${"119.0.6045.123"} | ${"119.0.6045.123"} | ${true} | ${false} | ${false} | ${true} | ${true}
${"119.0.6045.123"} | ${"119.0.6045.100"} | ${false} | ${true} | ${false} | ${false} | ${true}
${"119.0.6045.123"} | ${"119.0.6045.200"} | ${false} | ${false} | ${true} | ${false} | ${true}
${"119.0.6045.123"} | ${"119.0.7000.100"} | ${false} | ${false} | ${true} | ${false} | ${true}
${"119.0.6045.123"} | ${"119.0.5000.100"} | ${false} | ${true} | ${false} | ${false} | ${true}
${"119.0.6045.123"} | ${"119.1.6045.100"} | ${false} | ${false} | ${true} | ${false} | ${true}
${"119.0.6045.123"} | ${"120.0.6045.100"} | ${false} | ${false} | ${true} | ${false} | ${true}
${"119.0.6045.123"} | ${"118.0.6045.100"} | ${false} | ${true} | ${false} | ${false} | ${true}
${"119.0.6045.123"} | ${"119.0.6045.122"} | ${false} | ${true} | ${false} | ${false} | ${true}
`('compare "$a" and "$b"', ({ a, b, equals, greaterThan, lessThan }) => {
const v1 = new StaticVersion(a);
const v2 = new StaticVersion(b);
expect(v1.equals(v2)).toBe(equals);
expect(v1.greaterThan(v2)).toBe(greaterThan);
expect(v1.lessThan(v2)).toBe(lessThan);
expect(v1.greaterThanOrEqual(v2)).toBe(greaterThan || equals);
expect(v1.lessThanOrEqual(v2)).toBe(lessThan || equals);
});
describe("parse", () => {
test.each([
[
"119.0.6045.123",
{ type: "four-parts", major: 119, minor: 0, build: 6045, patch: 123 },
],
["119.0.6045", { type: "four-parts", major: 119, minor: 0, build: 6045 }],
["119.0", { type: "four-parts", major: 119, minor: 0 }],
["119", { type: "four-parts", major: 119 }],
["119.0.6045.x", { type: "four-parts", major: 119, minor: 0, build: 6045 }],
["119.0.x", { type: "four-parts", major: 119, minor: 0 }],
["119.x", { type: "four-parts", major: 119 }],
["latest", { type: "latest" }],
["beta", { type: "channel", channel: "beta" }],
["stable", { type: "channel", channel: "stable" }],
["canary", { type: "channel", channel: "canary" }],
["123456", { type: "snapshot", snapshot: 123456 }],
])("parse %s", (version, expected) => {
const v = parse(version);
expect(v.value).toEqual(expected);
});

describe("toString", () => {
test("return stringified version", () => {
const v = new StaticVersion("119.0.6045.123");
expect(v.toString()).toBe("119.0.6045.123");
});
test.each([
["119.0.6045.beta"],
["119.0.x.123"],
["x"],
["119.0.6045.123.456"],
["119.0.6045.-123"],
[""],
["invalid"],
])("throw an error for %s", (version) => {
expect(() => parse(version)).toThrow(`Invalid version: ${version}`);
});
});

describe("VersionSpec", () => {
describe("constructor", () => {
test("new instance", () => {
const version = new VersionSpec({
major: 119,
minor: 0,
build: 6045,
patch: 123,
});

expect(version.major).toBe(119);
expect(version.minor).toBe(0);
expect(version.build).toBe(6045);
expect(version.patch).toBe(123);
});

test.each([
["119.0.6045.123", [119, 0, 6045, 123]],
["119.0.6045", [119, 0, 6045]],
["119.0", [119, 0]],
["119", [119]],
["119.0.6045.x", [119, 0, 6045]],
["119.0.x", [119, 0]],
["119.x", [119]],
])("parse %s", (version, expected) => {
const v = new VersionSpec(version);
expect([v.major, v.minor, v.build, v.patch]).toEqual(expected);
});

test.each([
["119.0.6045.beta"],
["119.0.x.123"],
["x"],
["119.0.6045.123.456"],
["119.0.6045.-123"],
[""],
])("throw an error for %s", (version) => {
expect(() => new VersionSpec(version)).toThrow(
`Invalid version: ${version}`,
);
});
});

describe("toString", () => {
test.each([
["119.0.6045.123", "119.0.6045.123"],
["119", "119"],
])("return %s for %s", (expected, version) => {
const v = new VersionSpec(version);
["latest", "latest"],
["123456", "123456"],
])("return %s for %s", (spec, expected) => {
const v = parse(spec);
expect(v.toString()).toBe(expected);
});
});

describe("satisfies", () => {
test.each`
spec | version | satisfies
spec | target | satisfies
${"119.0.6045.123"} | ${"119.0.6045.123"} | ${true}
${"119.0.6045"} | ${"119.0.6045.123"} | ${true}
${"119"} | ${"119.0.6045.123"} | ${true}
${"119.0.6045.123"} | ${"119.0.6045.100"} | ${false}
${"119.0.6000"} | ${"119.0.6045.100"} | ${false}
${"120"} | ${"119.0.6045.100"} | ${false}
`("return if $spec satisfies $version", ({ spec, version, satisfies }) => {
const s = new VersionSpec(spec);
const v = new StaticVersion(version);
expect(s.satisfies(v)).toBe(satisfies);
${"latest"} | ${"119.0.6045.100"} | ${false}
${"latest"} | ${"latest"} | ${true}
${"123456"} | ${"123456"} | ${true}
${"123456"} | ${"123457"} | ${false}
`("return if $spec satisfies $target", ({ spec, target, satisfies }) => {
const v = parse(spec);
expect(v.satisfies(target)).toBe(satisfies);
});
});

describe("compare", () => {
test.each`
a | b | gt | lt
${"119.0.6045.123"} | ${"119.0.6045.123"} | ${false} | ${false}
${"119.0.6045.123"} | ${"119.0.6045.100"} | ${true} | ${false}
${"119.0.6045.123"} | ${"119.0.6045.200"} | ${false} | ${true}
${"119.0.6045.123"} | ${"119.0.7000.100"} | ${false} | ${true}
${"119.0.6045.123"} | ${"119.0.5000.100"} | ${true} | ${false}
${"119.0.6045.123"} | ${"119.1.6045.100"} | ${false} | ${true}
${"119.0.6045.123"} | ${"120.0.6045.100"} | ${false} | ${true}
${"119.0.6045.123"} | ${"118.0.6045.100"} | ${true} | ${false}
${"119.0.6045.123"} | ${"119.0.6045.122"} | ${true} | ${false}
${"119"} | ${"119.0.6045.123"} | ${false} | ${false}
${"123456"} | ${"123456"} | ${false} | ${false}
${"123456"} | ${"123457"} | ${false} | ${true}
${"latest"} | ${"latest"} | ${false} | ${false}
${"latest"} | ${"stable"} | ${false} | ${false}
${"119.0.6045.123"} | ${"latest"} | ${false} | ${false}
`('compare "$a" and "$b"', ({ a, b, gt, lt }) => {
const v1 = parse(a);

expect(v1.gt(b)).toBe(gt);
expect(v1.lt(b)).toBe(lt);
});
});
});
Loading

0 comments on commit e88eaf7

Please sign in to comment.