Files
makelore/tests/unit/gpu-fallback.test.ts

56 lines
2.0 KiB
TypeScript

import { mkdirSync, mkdtempSync, readFileSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { afterEach, describe, expect, it } from 'vitest';
import {
GPU_CRASH_THRESHOLD,
GPU_CRASH_WINDOW_MS,
readGpuFallbackState,
recordGpuCrash,
shouldUseSoftwareRendering,
} from '../../electron/main/gpu-fallback';
const temporaryDirectories: string[] = [];
afterEach(() => {
for (const directory of temporaryDirectories.splice(0)) {
rmSync(directory, { recursive: true, force: true });
}
});
describe('GPU fallback policy', () => {
it('enables software rendering only after repeated recent GPU failures', () => {
const now = 1_000_000;
expect(shouldUseSoftwareRendering({ state: null, now })).toBe(false);
expect(shouldUseSoftwareRendering({
state: { crashCount: GPU_CRASH_THRESHOLD, lastCrashAt: now, reason: 'crashed:1' },
now,
})).toBe(true);
expect(shouldUseSoftwareRendering({
state: {
crashCount: GPU_CRASH_THRESHOLD,
lastCrashAt: now - GPU_CRASH_WINDOW_MS - 1,
reason: 'crashed:1',
},
now,
})).toBe(false);
expect(shouldUseSoftwareRendering({ cliDisabled: true, now })).toBe(true);
});
it('persists an atomic crash counter and ignores malformed state', () => {
const directory = mkdtempSync(join(tmpdir(), 'makelore-gpu-'));
temporaryDirectories.push(directory);
const filePath = join(directory, 'nested', 'gpu-fallback.json');
const first = recordGpuCrash(filePath, 'crashed:9', 10);
const second = recordGpuCrash(filePath, 'oom:137', 20);
expect(first.crashCount).toBe(1);
expect(second.crashCount).toBe(2);
expect(readGpuFallbackState(filePath, 20)).toEqual(second);
expect(JSON.parse(readFileSync(filePath, 'utf8'))).toEqual(second);
mkdirSync(join(directory, 'bad'), { recursive: true });
const malformedPath = join(directory, 'bad', 'gpu-fallback.json');
expect(readGpuFallbackState(malformedPath)).toBeNull();
});
});