Files
hermes-desktop/tests/server/profile-delete-managed-gateway.test.ts
T
toor 01d9e301fc
Build / build (push) Canceled after 0s
Playwright / browser (push) Canceled after 0s
initialize Electron desktop app and remove unused files
2026-10-25 01:09:01 +08:00

83 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { EventEmitter } from 'events'
import { mkdir, mkdtemp, rm, writeFile } from 'fs/promises'
import { tmpdir } from 'os'
import { join } from 'path'
import { afterEach, describe, expect, it, vi } from 'vitest'
const originalEnv = { ...process.env }
const originalPlatform = Object.getOwnPropertyDescriptor(process, 'platform')
class FakeChild extends EventEmitter {
pid: number
killSignals: string[] = []
constructor(pid: number) {
super()
this.pid = pid
}
unref() { /* no-op */ }
kill(signal?: string) {
this.killSignals.push(signal || 'SIGTERM')
return true
}
}
let fakeChildren: FakeChild[] = []
vi.mock('../../packages/server/src/services/hermes/hermes-process', () => ({
execHermesWithBin: vi.fn().mockResolvedValue({ stdout: '', stderr: '' }),
spawnHermesWithBin: vi.fn(() => {
const child = new FakeChild(20000 + fakeChildren.length)
fakeChildren.push(child)
return child
}),
}))
afterEach(() => {
vi.useRealTimers()
vi.restoreAllMocks()
vi.resetModules()
process.env = { ...originalEnv }
if (originalPlatform) Object.defineProperty(process, 'platform', originalPlatform)
fakeChildren = []
})
describe('profile delete managed gateway lifecycle', () => {
it('reproduces #1633 and proves delete prep suppresses managed respawn', async () => {
vi.useFakeTimers()
vi.resetModules()
// 固定 platform:停止网关的手段随平台不同(POSIX 走 child.kill('SIGTERM'),
// Windows 走 taskkill 杀进程树)。不固定的话这个用例在 Windows 上会因为
// taskkill 是异步的而读不到 killSignals,而且会真的拿假 pid 去杀进程。
// Windows 分支由 gateway-respawn.test.ts 单独覆盖。
Object.defineProperty(process, 'platform', { value: 'linux' })
const home = await mkdtemp(join(tmpdir(), 'wui-1633-'))
process.env.HERMES_HOME = home
process.env.HERMES_BIN = '/usr/bin/hermes'
const profileDir = join(home, 'profiles', 'work')
await mkdir(profileDir, { recursive: true })
await writeFile(join(profileDir, 'config.yaml'), 'model:\n default: test\n', 'utf-8')
try {
const { startGatewayRunManaged } = await import('../../packages/server/src/services/hermes/gateway-runner')
const { prepareGatewayForProfileDelete } = await import('../../packages/server/src/services/hermes/gateway-autostart')
startGatewayRunManaged('/usr/bin/hermes', { profileDir })
expect(fakeChildren).toHaveLength(1)
const prep = prepareGatewayForProfileDelete('work')
expect(fakeChildren[0].killSignals).toEqual(['SIGTERM'])
fakeChildren[0].emit('exit', 0, 'SIGTERM')
await prep
await vi.advanceTimersByTimeAsync(6000)
expect(fakeChildren).toHaveLength(1)
} finally {
await rm(home, { recursive: true, force: true })
}
})
})