Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions packages/engine/src/services/browserManager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ import {
resolveBrowserGpuMode,
} from "./browserManager.js";

vi.mock("./systemMemory.js", async (importOriginal) => {
const actual = await importOriginal<typeof import("./systemMemory.js")>();
return { ...actual, getSystemTotalMb: vi.fn(() => 32768) };
});

import { getSystemTotalMb, LOW_MEMORY_TOTAL_MB_THRESHOLD } from "./systemMemory.js";

const mockGetSystemTotalMb = vi.mocked(getSystemTotalMb);

describe("buildChromeArgs browser GPU mode", () => {
const base = { width: 1920, height: 1080 };

Expand Down Expand Up @@ -308,3 +317,78 @@ describe("browser pool", () => {
await acquirePromise.catch(() => {});
});
});

describe("memory-adaptive Chrome flags", () => {
const base = { width: 1920, height: 1080 };

beforeEach(() => {
mockGetSystemTotalMb.mockReturnValue(32768);
});

afterEach(() => {
mockGetSystemTotalMb.mockReturnValue(32768);
});

function heapFlag(args: string[]): number | null {
const flag = args.find((a) => a.includes("--max-old-space-size="));
if (!flag) return null;
return parseInt(flag.match(/--max-old-space-size=(\d+)/)?.[1] ?? "", 10);
}

function gpuBudget(args: string[]): number {
const flag = args.find((a) => a.startsWith("--force-gpu-mem-available-mb="))!;
return parseInt(flag.split("=")[1]!, 10);
}

it("does not set heap limit above threshold", () => {
mockGetSystemTotalMb.mockReturnValue(LOW_MEMORY_TOTAL_MB_THRESHOLD + 1);
expect(heapFlag(buildChromeArgs(base))).toBeNull();
});

it("scales heap to total/8 at threshold", () => {
mockGetSystemTotalMb.mockReturnValue(LOW_MEMORY_TOTAL_MB_THRESHOLD);
expect(heapFlag(buildChromeArgs(base))).toBe(Math.floor(LOW_MEMORY_TOTAL_MB_THRESHOLD / 8));
});

it("scales heap to total/8 on 6 GB systems", () => {
mockGetSystemTotalMb.mockReturnValue(6144);
expect(heapFlag(buildChromeArgs(base))).toBe(768);
});

it("uses proportional heap at 4 GB boundary", () => {
mockGetSystemTotalMb.mockReturnValue(4096);
expect(heapFlag(buildChromeArgs(base))).toBe(512);
});

it("uses 256 MB heap floor below 4 GB", () => {
mockGetSystemTotalMb.mockReturnValue(3072);
expect(heapFlag(buildChromeArgs(base))).toBe(256);
});

it("scales GPU budget to total/4 at threshold", () => {
mockGetSystemTotalMb.mockReturnValue(LOW_MEMORY_TOTAL_MB_THRESHOLD);
expect(gpuBudget(buildChromeArgs(base))).toBe(Math.floor(LOW_MEMORY_TOTAL_MB_THRESHOLD / 4));
});

it("uses proportional GPU budget at 4 GB boundary", () => {
mockGetSystemTotalMb.mockReturnValue(4096);
expect(gpuBudget(buildChromeArgs(base))).toBe(1024);
});

it("switches to total/2 GPU and no heap limit just above threshold", () => {
const above = LOW_MEMORY_TOTAL_MB_THRESHOLD + 1;
mockGetSystemTotalMb.mockReturnValue(above);
expect(gpuBudget(buildChromeArgs(base))).toBe(Math.floor(above / 2));
expect(heapFlag(buildChromeArgs(base))).toBeNull();
});

it("scales GPU budget to total/2 well above threshold", () => {
mockGetSystemTotalMb.mockReturnValue(LOW_MEMORY_TOTAL_MB_THRESHOLD * 2);
expect(gpuBudget(buildChromeArgs(base))).toBe(LOW_MEMORY_TOTAL_MB_THRESHOLD);
});

it("uses 512 MB GPU budget below 4 GB", () => {
mockGetSystemTotalMb.mockReturnValue(3072);
expect(gpuBudget(buildChromeArgs(base))).toBe(512);
});
});
4 changes: 2 additions & 2 deletions packages/engine/src/services/browserManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -512,14 +512,14 @@ function getGpuMemBudgetMb(): number {

const total = getSystemTotalMb();
if (total < 4096) return 512;
if (total <= LOW_MEMORY_TOTAL_MB_THRESHOLD) return 1024;
if (total <= LOW_MEMORY_TOTAL_MB_THRESHOLD) return Math.floor(total / 4);
return Math.min(Math.floor(total / 2), 16384);
}

function getLowMemoryFlags(): string[] {
const total = getSystemTotalMb();
if (total > LOW_MEMORY_TOTAL_MB_THRESHOLD) return [];
const heapMb = total < 4096 ? 256 : 512;
const heapMb = total < 4096 ? 256 : Math.floor(total / 8);
return [`--js-flags=--max-old-space-size=${heapMb}`];
}

Expand Down
Loading