import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; vi.mock('../../src/env', () => ({ env: { boxIdleMs: 1000 } })); vi.mock('../../src/runtime/docker', () => ({ ensureUserContainer: vi.fn((args: { username: string }) => Promise.resolve(`spoon-box-${args.username}`), ), stopWorkspaceContainer: vi.fn(() => Promise.resolve()), userContainerName: (username: string) => `spoon-box-${username}`, listWorkspaceContainerNames: vi.fn(() => Promise.resolve([])), })); const load = async () => await import('../../src/user-container'); describe('box registry', () => { beforeEach(() => vi.useFakeTimers()); afterEach(async () => { const module = await load(); module._resetBoxRegistryForTests(); vi.useRealTimers(); vi.resetModules(); vi.clearAllMocks(); }); test('serializes concurrent acquire into a single docker run', async () => { const module = await load(); const docker = await import('../../src/runtime/docker'); const [a, b] = await Promise.all([ module.acquireUserBox({ username: 'alice', workdir: '/w', containerHome: '/home/alice', }), module.acquireUserBox({ username: 'alice', workdir: '/w', containerHome: '/home/alice', }), ]); expect(docker.ensureUserContainer).toHaveBeenCalledTimes(1); expect(a.boxName).toBe('spoon-box-alice'); a.release(); vi.advanceTimersByTime(2000); expect(docker.stopWorkspaceContainer).not.toHaveBeenCalled(); b.release(); vi.advanceTimersByTime(2000); expect(docker.stopWorkspaceContainer).toHaveBeenCalledTimes(1); }); test('double-release of one handle does not reap a box held elsewhere', async () => { const module = await load(); const docker = await import('../../src/runtime/docker'); const a = await module.acquireUserBox({ username: 'bob', workdir: '/w', containerHome: '/home/bob', }); const b = await module.acquireUserBox({ username: 'bob', workdir: '/w', containerHome: '/home/bob', }); a.release(); a.release(); vi.advanceTimersByTime(2000); expect(docker.stopWorkspaceContainer).not.toHaveBeenCalled(); b.release(); vi.advanceTimersByTime(2000); expect(docker.stopWorkspaceContainer).toHaveBeenCalledTimes(1); }); test('reconcileExistingBoxes adopts orphans with zero refs and reaps them', async () => { const module = await load(); const docker = await import('../../src/runtime/docker'); ( docker.listWorkspaceContainerNames as unknown as ReturnType ).mockResolvedValueOnce(['spoon-box-carol']); await module.reconcileExistingBoxes(); expect(module.runningBoxUsernames().has('carol')).toBe(true); vi.advanceTimersByTime(2000); expect(docker.stopWorkspaceContainer).toHaveBeenCalledWith( 'spoon-box-carol', ); }); });