Skip to content

Commit

Permalink
feat(config): allow percentage value for workers option
Browse files Browse the repository at this point in the history
  • Loading branch information
syi0808 committed Jun 27, 2024
1 parent 0c6cc03 commit 6cdf19d
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 6 deletions.
1 change: 1 addition & 0 deletions packages/vitest/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ const external = [
'worker_threads',
'node:worker_threads',
'node:fs',
'node:os',
'node:stream',
'node:vm',
'inspector',
Expand Down
22 changes: 20 additions & 2 deletions packages/vitest/src/node/config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { cpus } from 'node:os'
import { resolveModule } from 'local-pkg'
import { normalize, relative, resolve } from 'pathe'
import c from 'picocolors'
Expand Down Expand Up @@ -52,6 +53,13 @@ function parseInspector(inspect: string | undefined | boolean | number) {
return { host, port: Number(port) || defaultInspectPort }
}

function getWorkersCountByPercentage(percent: string) {
const maxWorkersCount = cpus().length
const workersCountByPercentage = Math.round((Number.parseInt(percent) / 100) * maxWorkersCount)

return Math.max(1, Math.min(maxWorkersCount, workersCountByPercentage))
}

export function resolveApiServerConfig<Options extends ApiConfig & UserConfig>(
options: Options,
defaultPort: number,
Expand Down Expand Up @@ -176,11 +184,21 @@ export function resolveConfig(
}

if (resolved.maxWorkers) {
resolved.maxWorkers = Number(resolved.maxWorkers)
if (typeof options.maxWorkers === 'string' && options.maxWorkers.trim().endsWith('%')) {
resolved.maxWorkers = getWorkersCountByPercentage(options.maxWorkers)
}
else {
resolved.maxWorkers = Number(resolved.maxWorkers)
}
}

if (resolved.minWorkers) {
resolved.minWorkers = Number(resolved.minWorkers)
if (typeof options.minWorkers === 'string' && options.minWorkers.trim().endsWith('%')) {
resolved.minWorkers = getWorkersCountByPercentage(options.minWorkers)
}
else {
resolved.minWorkers = Number(resolved.minWorkers)
}
}

resolved.browser ??= {} as any
Expand Down
11 changes: 7 additions & 4 deletions packages/vitest/src/types/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -343,13 +343,13 @@ export interface InlineConfig {
poolOptions?: PoolOptions

/**
* Maximum number of workers to run tests in. `poolOptions.{threads,vmThreads}.maxThreads`/`poolOptions.forks.maxForks` has higher priority.
* Maximum number or percentage of workers to run tests in. `poolOptions.{threads,vmThreads}.maxThreads`/`poolOptions.forks.maxForks` has higher priority.
*/
maxWorkers?: number
maxWorkers?: number | string
/**
* Minimum number of workers to run tests in. `poolOptions.{threads,vmThreads}.minThreads`/`poolOptions.forks.minForks` has higher priority.
* Minimum number or percentage of workers to run tests in. `poolOptions.{threads,vmThreads}.minThreads`/`poolOptions.forks.minForks` has higher priority.
*/
minWorkers?: number
minWorkers?: number | string

/**
* Should all test files run in parallel. Doesn't affect tests running in the same file.
Expand Down Expand Up @@ -1009,6 +1009,9 @@ export interface ResolvedConfig
enabled: boolean
}
runner?: string

maxWorkers: number
minWorkers: number
}

export type ProjectConfig = Omit<
Expand Down
1 change: 1 addition & 0 deletions test/config/fixtures/workers-option/vitest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default {}
21 changes: 21 additions & 0 deletions test/config/test/workers-option.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { type UserConfig, expect, test, vi } from 'vitest'

import * as testUtils from '../../test-utils'

vi.mock('node:os', async importOriginal => ({
...(await importOriginal() as Record<any, any>),
cpus: vi.fn(() => Array.from({ length: 10 })),
}))

function runVitest(config: UserConfig) {
return testUtils.runVitest({ ...config, root: './fixtures/workers-option' })
}

test.each([
{ option: 'minWorkers' },
{ option: 'maxWorkers' },
] as const)('$option=50% should set resolved.$option=5', async ({ option }) => {
const { ctx } = await runVitest({ [option]: '50%' })

expect(ctx?.config[option]).toBe(5)
})

0 comments on commit 6cdf19d

Please sign in to comment.