Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

74 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { readFileSync } from "node:fs";
3import { test } from "node:test";
4
5import {
6 INSTANCE_TYPES,
7 STANDARD_INSTANCE,
8 instanceNamed,
9 machineNamed,
10 machineSize,
11 machines,
12 priceScale,
13 runnerMinutes,
14} from "../../../packages/contracts/src/instances.ts";
15
16import { SANDBOX_BINDINGS, jobNamespaceOf } from "./egress.ts";
17
18test("each label in the machine catalogue runs in its own class, bound and sized as wrangler.jsonc says", () => {
19 type Size = { vcpu: number; memory_mib: number; disk_mb: number };
20 // wrangler.jsonc's comments are whole lines.
21 const text = readFileSync(new URL("../wrangler.jsonc", import.meta.url), "utf8").replace(/^\s*\/\/.*$/gm, "");
22 const config = JSON.parse(text) as {
23 containers: { class_name: string; instance_type: unknown }[];
24 durable_objects: { bindings: { name: string; class_name: string }[] };
25 };
26 // The named Cloudflare instance types a machine may be, at the sizes
27 // Cloudflare gives them. A custom type would be a row here once the
28 // account may use them.
29 const named: Record<string, Size> = {
30 "standard-3": { vcpu: 2, memory_mib: 8 * 1024, disk_mb: 16_000 },
31 "standard-4": { vcpu: 4, memory_mib: 12 * 1024, disk_mb: 20_000 },
32 };
33 // Every class has a label, and every label a class.
34 assert.deepEqual(INSTANCE_TYPES.map((instance) => instance.sandboxClass).sort(), config.containers.map((container) => container.class_name).sort());
35 for (const instance of INSTANCE_TYPES) {
36 const type = config.containers.find((c) => c.class_name === instance.sandboxClass)?.instance_type;
37 const size = typeof type === "string" ? named[type] : undefined;
38 assert.ok(size, `${instance.sandboxClass}: ${JSON.stringify(type)}`);
39 assert.equal(type, instance.container, instance.label);
40 assert.deepEqual(
41 { vcpu: size.vcpu, memoryGib: size.memory_mib / 1024, diskGb: size.disk_mb / 1000 },
42 { vcpu: instance.vcpu, memoryGib: instance.memoryGib, diskGb: instance.diskGb },
43 instance.label,
44 );
45 // Its binding, here and in wrangler.jsonc, is what a job starts in.
46 const binding = SANDBOX_BINDINGS[instance.sandboxClass];
47 assert.ok(binding, `${instance.sandboxClass} has no binding in SANDBOX_BINDINGS`);
48 assert.ok(
49 config.durable_objects.bindings.some((b) => b.name === binding && b.class_name === instance.sandboxClass),
50 binding,
51 );
52 assert.equal(jobNamespaceOf({ [binding]: instance.label }, instance), instance.label);
53 }
54 // A class not deployed here: the job is not started on another machine.
55 assert.equal(jobNamespaceOf({ SANDBOX: "standard" }, INSTANCE_TYPES[2]!), null);
56 assert.equal(jobNamespaceOf({ SANDBOX: "standard" }, { sandboxClass: "Sandbox64Core" }), null);
57});
58
59test("runs-on labels are the catalogue's, and a job is charged its minutes rounded up", () => {
60 assert.equal(instanceNamed("ubuntu-latest"), STANDARD_INSTANCE);
61 assert.equal(instanceNamed("G1T-4Core").machine, "4-core");
62 assert.equal(instanceNamed("g1t-2core").machine, STANDARD_INSTANCE.machine);
63 assert.deepEqual(
64 machines().map((m) => [m.machine, m.microsPerMinute, machineSize(m)]),
65 [
66 ["2-core", 4000, "2 vCPU, 8 GiB, 16 GB"],
67 ["4-core", 7000, "4 vCPU, 12 GiB, 20 GB"],
68 ],
69 );
70 assert.equal(machineNamed("4-core")?.label, "g1t-4core");
71 assert.equal(machineNamed("8-core"), null);
72 assert.equal(priceScale(instanceNamed("g1t-4core")), 1.75);
73 assert.deepEqual([0, 1, 60, 61, 3600].map(runnerMinutes), [0, 1, 1, 2, 60]);
74});