Skip to content

Commit

Permalink
fix(workspace): support overring pool and poolOptions on project …
Browse files Browse the repository at this point in the history
…level (#4765)
  • Loading branch information
AriPerkkio committed Jan 9, 2024
1 parent 508fced commit e9fe418
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 13 deletions.
14 changes: 7 additions & 7 deletions docs/config/index.md
Expand Up @@ -655,7 +655,7 @@ Please, be aware of these issues when using this option. Vitest team cannot fix
- **Type:** `Record<'threads' | 'forks' | 'vmThreads', {}>`
- **Default:** `{}`

#### poolOptions.threads<NonProjectOption />
#### poolOptions.threads

Options for `threads` pool.

Expand Down Expand Up @@ -687,7 +687,7 @@ Maximum number of threads. You can also use `VITEST_MAX_THREADS` environment var

Minimum number of threads. You can also use `VITEST_MIN_THREADS` environment variable.

##### poolOptions.threads.singleThread<NonProjectOption />
##### poolOptions.threads.singleThread

- **Type:** `boolean`
- **Default:** `false`
Expand All @@ -710,7 +710,7 @@ Use Atomics to synchronize threads.

This can improve performance in some cases, but might cause segfault in older Node versions.

##### poolOptions.threads.isolate<NonProjectOption />
##### poolOptions.threads.isolate

- **Type:** `boolean`
- **Default:** `true`
Expand All @@ -728,7 +728,7 @@ Pass additional arguments to `node` in the threads. See [Command-line API | Node
Be careful when using, it as some options may crash worker, e.g. --prof, --title. See https://github.com/nodejs/node/issues/41103.
:::

#### poolOptions.forks<NonProjectOption />
#### poolOptions.forks

Options for `forks` pool.

Expand Down Expand Up @@ -760,14 +760,14 @@ Maximum number of forks.

Minimum number of forks.

##### poolOptions.forks.isolate<NonProjectOption />
##### poolOptions.forks.isolate

- **Type:** `boolean`
- **Default:** `true`

Isolate environment for each test file.

##### poolOptions.forks.singleFork<NonProjectOption />
##### poolOptions.forks.singleFork

- **Type:** `boolean`
- **Default:** `false`
Expand All @@ -792,7 +792,7 @@ Pass additional arguments to `node` process in the child processes. See [Command
Be careful when using, it as some options may crash worker, e.g. --prof, --title. See https://github.com/nodejs/node/issues/41103.
:::

#### poolOptions.vmThreads<NonProjectOption />
#### poolOptions.vmThreads

Options for `vmThreads` pool.

Expand Down
20 changes: 18 additions & 2 deletions packages/vitest/src/node/workspace.ts
Expand Up @@ -319,12 +319,28 @@ export class WorkspaceProject {

getSerializableConfig() {
const optimizer = this.config.deps?.optimizer
const poolOptions = this.config.poolOptions

// Resolve from server.config to avoid comparing against default value
const isolate = this.server?.config?.test?.isolate

return deepMerge({
...this.config,
coverage: this.ctx.config.coverage,

pool: this.ctx.config.pool,
poolOptions: this.ctx.config.poolOptions,
poolOptions: {
forks: {
singleFork: poolOptions?.forks?.singleFork ?? this.ctx.config.poolOptions?.forks?.singleFork ?? false,
isolate: poolOptions?.forks?.isolate ?? isolate ?? this.ctx.config.poolOptions?.forks?.isolate ?? true,
},
threads: {
singleThread: poolOptions?.threads?.singleThread ?? this.ctx.config.poolOptions?.threads?.singleThread ?? false,
isolate: poolOptions?.threads?.isolate ?? isolate ?? this.ctx.config.poolOptions?.threads?.isolate ?? true,
},
vmThreads: {
singleThread: poolOptions?.vmThreads?.singleThread ?? this.ctx.config.poolOptions?.vmThreads?.singleThread ?? false,
},
},

reporters: [],
deps: {
Expand Down
6 changes: 5 additions & 1 deletion packages/vitest/src/types/config.ts
Expand Up @@ -817,7 +817,6 @@ export type ProjectConfig = Omit<
| 'update'
| 'reporters'
| 'outputFile'
| 'pool'
| 'poolOptions'
| 'teardownTimeout'
| 'silent'
Expand All @@ -842,6 +841,11 @@ export type ProjectConfig = Omit<
> & {
sequencer?: Omit<SequenceOptions, 'sequencer' | 'seed'>
deps?: Omit<DepsOptions, 'moduleDirectories'>
poolOptions?: {
threads?: Pick<NonNullable<PoolOptions['threads']>, 'singleThread' | 'isolate'>
vmThreads?: Pick<NonNullable<PoolOptions['vmThreads']>, 'singleThread'>
forks?: Pick<NonNullable<PoolOptions['forks']>, 'singleFork' | 'isolate'>
}
}

export type RuntimeConfig = Pick<
Expand Down
11 changes: 8 additions & 3 deletions test/config/test/config-types.test-d.ts
Expand Up @@ -9,11 +9,16 @@ describe('define project helper', () => {
expectProjectTestConfig.toHaveProperty('name')
expectMainTestConfig.toHaveProperty('name')

expectProjectTestConfig.not.toHaveProperty('pool')
expectMainTestConfig.toHaveProperty('pool')

expectProjectTestConfig.not.toHaveProperty('coverage')
expectMainTestConfig.toHaveProperty('coverage')

expectProjectTestConfig.not.toHaveProperty('reporters')
expectMainTestConfig.toHaveProperty('reporters')
})

test('allows expected project fields on a project config', () => {
expectProjectTestConfig.toHaveProperty('pool')
expectProjectTestConfig.toHaveProperty('poolOptions')
})
})

Expand Down
12 changes: 12 additions & 0 deletions test/workspaces/space-pools/forks.test.ts
@@ -0,0 +1,12 @@
import { isMainThread } from 'node:worker_threads'
import { expect, test } from 'vitest'

test('is run in "node:child_process"', () => {
expect(isChildProcess()).toBe(true)
expect(isMainThread).toBe(true)
})

// TODO: Use from "src/utils/base.ts" after #4441
function isChildProcess(): boolean {
return !!process?.send
}
15 changes: 15 additions & 0 deletions test/workspaces/space-pools/isolate.test.ts
@@ -0,0 +1,15 @@
import { expect, test } from 'vitest'
import type { UserConfig } from 'vitest/config'

test('is isolated', () => {
// @ts-expect-error -- internal
const config: NonNullable<UserConfig['test']> = globalThis.__vitest_worker__.config

if (config.pool === 'forks') {
expect(config.poolOptions?.forks?.isolate).toBe(true)
}
else {
expect(config.pool).toBe('threads')
expect(config.poolOptions?.threads?.isolate).toBe(true)
}
})
15 changes: 15 additions & 0 deletions test/workspaces/space-pools/multi-worker.test.ts
@@ -0,0 +1,15 @@
import { expect, test } from 'vitest'
import type { UserConfig } from 'vitest/config'

test('is multi worker', () => {
// @ts-expect-error -- internal
const config: NonNullable<UserConfig['test']> = globalThis.__vitest_worker__.config

if (config.pool === 'forks') {
expect(config.poolOptions?.forks?.singleFork).toBe(false)
}
else {
expect(config.pool).toBe('threads')
expect(config.poolOptions?.threads?.singleThread).toBe(false)
}
})
15 changes: 15 additions & 0 deletions test/workspaces/space-pools/no-isolate.test.ts
@@ -0,0 +1,15 @@
import { expect, test } from 'vitest'
import type { UserConfig } from 'vitest/config'

test('is not isolated', () => {
// @ts-expect-error -- internal
const config: NonNullable<UserConfig['test']> = globalThis.__vitest_worker__.config

if (config.pool === 'forks') {
expect(config.poolOptions?.forks?.isolate).toBe(false)
}
else {
expect(config.pool).toBe('threads')
expect(config.poolOptions?.threads?.isolate).toBe(false)
}
})
15 changes: 15 additions & 0 deletions test/workspaces/space-pools/single-worker.test.ts
@@ -0,0 +1,15 @@
import { expect, test } from 'vitest'
import type { UserConfig } from 'vitest/config'

test('is single worker', () => {
// @ts-expect-error -- internal
const config: NonNullable<UserConfig['test']> = globalThis.__vitest_worker__.config

if (config.pool === 'forks') {
expect(config.poolOptions?.forks?.singleFork).toBe(true)
}
else {
expect(config.pool).toBe('threads')
expect(config.poolOptions?.threads?.singleThread).toBe(true)
}
})
12 changes: 12 additions & 0 deletions test/workspaces/space-pools/threads.test.ts
@@ -0,0 +1,12 @@
import { isMainThread } from 'node:worker_threads'
import { expect, test } from 'vitest'

test('is run in "node:worker_threads"', () => {
expect(isChildProcess()).toBe(false)
expect(isMainThread).toBe(false)
})

// TODO: Use from "src/utils/base.ts" after #4441
function isChildProcess(): boolean {
return !!process?.send
}
90 changes: 90 additions & 0 deletions test/workspaces/vitest.workspace.ts
Expand Up @@ -23,6 +23,96 @@ export default defineWorkspace([
},
},

// Projects testing pool and poolOptions
{
test: {
name: 'Threads pool',
include: [
'./space-pools/threads.test.ts',
'./space-pools/multi-worker.test.ts',
'./space-pools/isolate.test.ts',
],
pool: 'threads',
},
},
{
test: {
name: 'Single thread pool',
include: [
'./space-pools/threads.test.ts',
'./space-pools/single-worker.test.ts',
],
pool: 'threads',
poolOptions: { threads: { singleThread: true } },
},
},
{
test: {
name: 'Non-isolated thread pool #1',
include: [
'./space-pools/threads.test.ts',
'./space-pools/no-isolate.test.ts',
],
pool: 'threads',
poolOptions: { threads: { isolate: false } },
},
},
{
test: {
name: 'Non-isolated thread pool #2',
include: [
'./space-pools/threads.test.ts',
'./space-pools/no-isolate.test.ts',
],
pool: 'threads',
isolate: false,
},
},
{
test: {
name: 'Forks pool',
include: [
'./space-pools/forks.test.ts',
'./space-pools/multi-worker.test.ts',
'./space-pools/isolate.test.ts',
],
pool: 'forks',
},
},
{
test: {
name: 'Single fork pool',
include: [
'./space-pools/forks.test.ts',
'./space-pools/single-worker.test.ts',
],
pool: 'forks',
poolOptions: { forks: { singleFork: true } },
},
},
{
test: {
name: 'Non-isolated fork pool #1',
include: [
'./space-pools/forks.test.ts',
'./space-pools/no-isolate.test.ts',
],
pool: 'forks',
poolOptions: { forks: { isolate: false } },
},
},
{
test: {
name: 'Non-isolated fork pool #2',
include: [
'./space-pools/forks.test.ts',
'./space-pools/no-isolate.test.ts',
],
pool: 'forks',
isolate: false,
},
},

// These two projects run on same environment but still transform
// a single file differently due to Vite plugins
{
Expand Down

0 comments on commit e9fe418

Please sign in to comment.