Skip to content
Source
Sign inSign up
Open History to see the last commit

admission.test.ts

35 lines1.5 KB

1import {
2 MAX_PACK_BYTES,
3 PUSH_MEMORY_BUDGET_MB,
4 pushPermitsFor,
5 STAGE_BATCH_BYTES,
6} from "@alchemy.run/git/RepoObject";
7/**
8 * Push admission (packages/git/src/RepoObject.ts `pushPermitsFor`): the permit a
9 * push takes from the isolate-wide memory gate must reflect what it can
10 * hold at once — a spilled push never its body, an in-memory push never
11 * the caches' ceilings (DESIGN §21.2, §22.5).
12 */
13import { BACKPRESSURE_BYTES, RETAIN_BYTES } from "@alchemy.run/git/Store/StreamingSource";
14import { describe, expect, test } from "@alchemy.run/test";
15​
16const MiB = 1024 * 1024;
17const spilled = Math.ceil((RETAIN_BYTES + BACKPRESSURE_BYTES + STAGE_BATCH_BYTES) / MiB);
18​
19describe("pushPermitsFor", { tags: ["unit", "local"] }, () => {
20 test("a spilled push is charged its working set, never its body", () => {
21 expect(pushPermitsFor(MAX_PACK_BYTES + 1)).toBe(spilled);
22 expect(pushPermitsFor(400 * MiB)).toBe(spilled);
23 expect(pushPermitsFor(undefined)).toBe(spilled);
24 expect(pushPermitsFor(Number.NaN)).toBe(spilled);
25 expect(spilled).toBeLessThan(PUSH_MEMORY_BUDGET_MB);
26 });
27​
28 test("an in-memory push is charged by its size; tiny pushes stay cheap", () => {
29 expect(pushPermitsFor(0)).toBe(1);
30 expect(pushPermitsFor(1024)).toBe(3);
31 expect(pushPermitsFor(MAX_PACK_BYTES)).toBe(2 * (MAX_PACK_BYTES / MiB) + 1);
32 // Several small pushes fit alongside one large one.
33 expect(spilled + 4 * pushPermitsFor(1024)).toBeLessThanOrEqual(PUSH_MEMORY_BUDGET_MB);
34 });
35});