Skip to content

Commit dfe81a6

Browse files
authored
fix(pool): throw if user's tests use process.send() (#8125)
1 parent c69be1f commit dfe81a6

File tree

5 files changed

+52
-2
lines changed

5 files changed

+52
-2
lines changed

packages/vitest/src/node/pools/forks.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,21 @@ function createChildProcessChannel(project: TestProject, collect = false) {
3030
const rpc = createBirpc<RunnerRPC, RuntimeRPC>(createMethodsRPC(project, { cacheFs: true, collect }), {
3131
eventNames: ['onCancel'],
3232
serialize: v8.serialize,
33-
deserialize: v => v8.deserialize(Buffer.from(v)),
33+
deserialize: (v) => {
34+
try {
35+
return v8.deserialize(Buffer.from(v))
36+
}
37+
catch (error) {
38+
let stringified = ''
39+
40+
try {
41+
stringified = `\nReceived value: ${JSON.stringify(v)}`
42+
}
43+
catch {}
44+
45+
throw new Error(`[vitest-pool]: Unexpected call to process.send(). Make sure your test cases are not interfering with process's channel.${stringified}`, { cause: error })
46+
}
47+
},
3448
post(v) {
3549
emitter.emit(events.message, v)
3650
},

packages/vitest/src/node/pools/vmForks.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,21 @@ function createChildProcessChannel(project: TestProject, collect: boolean) {
3535
{
3636
eventNames: ['onCancel'],
3737
serialize: v8.serialize,
38-
deserialize: v => v8.deserialize(Buffer.from(v)),
38+
deserialize: (v) => {
39+
try {
40+
return v8.deserialize(Buffer.from(v))
41+
}
42+
catch (error) {
43+
let stringified = ''
44+
45+
try {
46+
stringified = `\nReceived value: ${JSON.stringify(v)}`
47+
}
48+
catch {}
49+
50+
throw new Error(`[vitest-pool]: Unexpected call to process.send(). Make sure your test cases are not interfering with process's channel.${stringified}`, { cause: error })
51+
}
52+
},
3953
post(v) {
4054
emitter.emit(events.message, v)
4155
},
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { test } from "vitest";
2+
3+
test("calls IPC channel", () => {
4+
if (!process.send) {
5+
throw new Error("Expected test case to run inside child_process")
6+
}
7+
8+
process.send({ "not serialized": "with v8 serializer" })
9+
})
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default {}

test/cli/test/forks-channel.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { expect, test } from 'vitest'
2+
import { runVitest } from '../../test-utils'
3+
4+
test.each(['forks', 'vmForks'] as const)('test case\'s process.send() calls are handled', async (pool) => {
5+
const { stderr } = await runVitest({
6+
root: './fixtures/forks-channel',
7+
pool,
8+
})
9+
10+
expect(stderr).toContain('⎯⎯⎯⎯ Unhandled Rejection ⎯⎯⎯⎯⎯')
11+
expect(stderr).toContain('Error: [vitest-pool]: Unexpected call to process.send(). Make sure your test cases are not interfering with process\'s channel.')
12+
})

0 commit comments

Comments
 (0)