Skip to content

Commit

Permalink
fix!: change default pool to 'forks'
Browse files Browse the repository at this point in the history
  • Loading branch information
AriPerkkio committed Apr 2, 2024
1 parent ffec1dc commit c8a4e21
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 26 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@ jobs:
- name: Test
run: pnpm run test:ci

- name: Test No Threads
run: pnpm run test:ci:no-threads
- name: Test Threads
run: pnpm run test:ci:threads

- name: Test Vm Threads
run: pnpm run test:ci:vm-threads
Expand Down
2 changes: 1 addition & 1 deletion docs/config/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ By providing an object instead of a string you can define individual outputs whe
### pool<NonProjectOption /> <Badge type="info">1.0.0+</Badge> {#pool}

- **Type:** `'threads' | 'forks' | 'vmThreads' | 'vmForks'`
- **Default:** `'threads'`
- **Default:** `'forks'` (in v1 `'threads'`)
- **CLI:** `--pool=threads`

Pool used to run tests in.
Expand Down
38 changes: 29 additions & 9 deletions docs/guide/common-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ This error can happen when NodeJS's `fetch` is used with default [`pool: 'thread

As work-around you can switch to [`pool: 'forks'`](/config/#forks) or [`pool: 'vmForks'`](/config/#vmforks).

Specify `pool` in your configuration file:

```ts
::: code-group
```ts [vitest.config.js]
import { defineConfig } from 'vitest/config'

export default defineConfig({
Expand All @@ -76,12 +75,33 @@ export default defineConfig({
},
})
```
```bash [CLI]
vitest --pool=forks
```
:::

Or in your `package.json` scripts:
## Segfaults and native code errors

```diff
scripts: {
- "test": "vitest"
+ "test": "vitest --pool=forks"
}
Running [native NodeJS modules](https://nodejs.org/api/addons.html) in `pool: 'threads'` can run into cryptic errors coming from the native code.

- `Segmentation fault (core dumped)`
- `thread '<unnamed>' panicked at 'assertion failed`
- `Abort trap: 6`
- `internal error: entered unreachable code`

In these cases the native module is likely not built to be multi-thread safe. As work-around, you can switch to `pool: 'forks'` which runs the test cases in multiple `node:child_process` instead of multiple `node:worker_threads`.

::: code-group
```ts [vitest.config.js]
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
pool: 'forks',
},
})
```
```bash [CLI]
vitest --pool=forks
```
:::
23 changes: 23 additions & 0 deletions docs/guide/improving-performance.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Improving Performance

## Test isolation

By default Vitest runs every test file in an isolated environment based on the [pool](/config/#pool):

- `threads` pool runs every test file in a separate [`Worker`](https://nodejs.org/api/worker_threads.html#class-worker)
Expand Down Expand Up @@ -49,3 +51,24 @@ export default defineConfig({
})
```
:::

## Pool

By default Vitest runs tests in `pool: 'forks'`. While `'forks'` pool is better for compatibility issues ([hanging process](/guide/common-errors.html#failed-to-terminate-worker) and [segfaults](/guide/common-errors.html#segfaults-and-native-code-errors)), it may be slightly slower than `pool: 'threads'` in larger projects.

You can try to improve test run time by switching `pool` option in configuration:

::: code-group
```bash [CLI]
vitest --pool=threads
```
```ts [vitest.config.js]
import { defineConfig } from 'vitest/config'

export default defineConfig({
test: {
pool: 'threads',
},
})
```
:::
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"test:all": "CI=true pnpm -r --stream run test --allowOnly",
"test:ci": "CI=true pnpm -r --reporter-hide-prefix --stream --filter !test-browser --filter !test-esm --filter !test-browser run test --allowOnly",
"test:ci:vm-threads": "CI=true pnpm -r --reporter-hide-prefix --stream --filter !test-coverage --filter !test-single-thread --filter !test-browser --filter !test-esm --filter !test-network-imports --filter !test-browser --filter !example-react-testing-lib-msw run test --allowOnly --pool vmThreads",
"test:ci:no-threads": "CI=true pnpm -r --reporter-hide-prefix --stream --filter !test-vm-threads --filter !test-coverage --filter !test-watch --filter !test-bail --filter !test-esm --filter !test-browser run test --allowOnly --pool forks",
"test:ci:threads": "CI=true pnpm -r --reporter-hide-prefix --stream --filter !test-vm-threads --filter !test-coverage --filter !test-watch --filter !test-bail --filter !test-esm --filter !test-browser run test --allowOnly --pool threads",
"typecheck": "tsc -p tsconfig.check.json --noEmit",
"typecheck:why": "tsc -p tsconfig.check.json --noEmit --explainFiles > explainTypes.txt",
"ui:build": "vite build packages/ui",
Expand Down
2 changes: 1 addition & 1 deletion packages/vitest/src/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const config = {
watch: !isCI,
globals: false,
environment: 'node' as const,
pool: 'threads' as const,
pool: 'forks' as const,
clearMocks: false,
restoreMocks: false,
mockReset: false,
Expand Down
11 changes: 4 additions & 7 deletions test/config/test/chai-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ describe('truncateThreshold', () => {
ok 6 - test-each-title.test.ts > [ 'one', 'two', 'three', 'four', …(1) ]
ok 7 - test-each-title.test.ts > { one: 1, two: 2, three: 3 }
ok 8 - test-each-title.test.ts > { one: 1, two: 2, three: 3, four: 4 }
ok 9 - test-each-title.test.ts > { one: 1, two: 2, three: 3, …(2) }
"
ok 9 - test-each-title.test.ts > { one: 1, two: 2, three: 3, …(2) }"
`)
expect(result.exitCode).toBe(0)
})
Expand All @@ -43,8 +42,7 @@ describe('truncateThreshold', () => {
ok 6 - test-each-title.test.ts > [ 'one', 'two', 'three', 'four', …(1) ]
ok 7 - test-each-title.test.ts > { one: 1, two: 2, three: 3 }
ok 8 - test-each-title.test.ts > { one: 1, two: 2, three: 3, four: 4 }
ok 9 - test-each-title.test.ts > { one: 1, two: 2, three: 3, …(2) }
"
ok 9 - test-each-title.test.ts > { one: 1, two: 2, three: 3, …(2) }"
`)
expect(result.exitCode).toBe(0)
})
Expand All @@ -68,14 +66,13 @@ describe('truncateThreshold', () => {
ok 6 - test-each-title.test.ts > [ 'one', 'two', 'three', 'four', 'five' ]
ok 7 - test-each-title.test.ts > { one: 1, two: 2, three: 3 }
ok 8 - test-each-title.test.ts > { one: 1, two: 2, three: 3, four: 4 }
ok 9 - test-each-title.test.ts > { one: 1, two: 2, three: 3, four: 4, five: 5 }
"
ok 9 - test-each-title.test.ts > { one: 1, two: 2, three: 3, four: 4, five: 5 }"
`)
expect(result.exitCode).toBe(0)
})
})

function cleanOutput(output: string) {
// remove non-deterministic output
return output.replaceAll(/\s*# time=.*/g, '')
return output.replaceAll(/\s*# time=.*/g, '').trim()
}
2 changes: 1 addition & 1 deletion test/config/test/failures.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ test('boolean flag 100 should not crash CLI', async () => {

test('nextTick cannot be mocked inside child_process', async () => {
const { stderr } = await runVitest({
pool: 'forks',
fakeTimers: { toFake: ['nextTick'] },
include: ['./fixtures/test/fake-timers.test.ts'],
})
Expand All @@ -153,6 +152,7 @@ test('nextTick cannot be mocked inside child_process', async () => {

test('nextTick can be mocked inside worker_threads', async () => {
const { stderr } = await runVitest({
pool: 'threads',
fakeTimers: { toFake: ['nextTick'] },
include: ['./fixtures/test/fake-timers.test.ts'],
})
Expand Down
1 change: 1 addition & 0 deletions test/test-utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ function captureLogs() {

const originalStdoutWrite = process.stdout.write
process.stdout.write = streams.stdout.write.bind(streams.stdout) as any
process.stdout.isTTY = false

const originalStderrWrite = process.stderr.write
process.stderr.write = streams.stderr.write.bind(streams.stderr) as any
Expand Down
6 changes: 2 additions & 4 deletions test/watch/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ export default defineConfig({
testTimeout: process.env.CI ? 60_000 : 10_000,

// Test cases may have side effects, e.g. files under fixtures/ are modified on the fly to trigger file watchers
poolOptions: {
threads: { singleThread: true },
vmThreads: { singleThread: true },
},
fileParallelism: false,

// TODO: Fix flakiness and remove
allowOnly: true,
bail: 1,
},
})

0 comments on commit c8a4e21

Please sign in to comment.