fix(install-e2e): release inherited pipes after launcher exit
This commit is contained in:
@@ -6,11 +6,14 @@ import { expect, it, vi } from 'vitest'
|
||||
const { observeProcessClose } = createRequire(import.meta.url)('../tests/install/e2e-assets/process-close.cjs')
|
||||
|
||||
it('waits for native close, not exit, and retains a close observed before hand-off', async () => {
|
||||
const child = new EventEmitter()
|
||||
const pipe = { destroy: vi.fn() }
|
||||
const child = Object.assign(new EventEmitter(), { stdio: [null, pipe], exitCode: null, signalCode: null })
|
||||
const waitForClose = observeProcessClose(child)
|
||||
expect(pipe.destroy).not.toHaveBeenCalled()
|
||||
let finished = false
|
||||
const completion = waitForClose().then(() => { finished = true })
|
||||
child.emit('exit', 0)
|
||||
expect(pipe.destroy).toHaveBeenCalledOnce()
|
||||
await Promise.resolve()
|
||||
expect(finished).toBe(false)
|
||||
child.emit('close', 0)
|
||||
@@ -22,7 +25,7 @@ it('waits for native close, not exit, and retains a close observed before hand-o
|
||||
it('fails if the launched process never closes', async () => {
|
||||
vi.useFakeTimers()
|
||||
try {
|
||||
const waitForClose = observeProcessClose(new EventEmitter())
|
||||
const waitForClose = observeProcessClose(Object.assign(new EventEmitter(), { stdio: [], exitCode: null, signalCode: null }))
|
||||
const completion = expect(waitForClose(2_000)).rejects.toThrow('Electron process did not close')
|
||||
await vi.advanceTimersByTimeAsync(2_000)
|
||||
await completion
|
||||
|
||||
@@ -6,6 +6,13 @@ function observeProcessClose(child) {
|
||||
closed = true
|
||||
resolve()
|
||||
}))
|
||||
// Windows descendants can inherit pipe handles and postpone 'close' after
|
||||
// the launch process exits. Release our handles, never kill descendants.
|
||||
const releasePipes = () => {
|
||||
for (const stream of child.stdio) stream?.destroy()
|
||||
}
|
||||
child.once('exit', releasePipes)
|
||||
if (child.exitCode !== null || child.signalCode !== null) releasePipes()
|
||||
return async function waitForClose(timeoutMs = 120_000) {
|
||||
if (closed) return
|
||||
let timer
|
||||
|
||||
Reference in New Issue
Block a user