diff --git a/packages/vitest/src/node/pool.ts b/packages/vitest/src/node/pool.ts index 2a78de6ae08d..245565f7bf33 100644 --- a/packages/vitest/src/node/pool.ts +++ b/packages/vitest/src/node/pool.ts @@ -123,7 +123,7 @@ export function createPool(ctx: Vitest): ProcessPool { workerId: workerId++, }, project, - env: options.env, + env: { ...options.env, ...project.config.env }, execArgv: [...options.execArgv, ...project.config.execArgv], worker: pool, isolate: project.config.isolate, diff --git a/packages/vitest/src/node/pools/pool.ts b/packages/vitest/src/node/pools/pool.ts index 3251c34bf3c9..4631e422c8f8 100644 --- a/packages/vitest/src/node/pools/pool.ts +++ b/packages/vitest/src/node/pools/pool.ts @@ -281,17 +281,6 @@ function isEqualRunner(runner: PoolRunner, task: PoolTask) { runner.worker.name === task.worker && runner.project === task.project && runner.environment === task.context.environment.name - && runner.worker.execArgv.every((arg, index) => task.execArgv[index] === arg) - && isEnvEqual(runner.worker.env, task.env) + && (!runner.worker.canReuse || runner.worker.canReuse(task)) ) } - -function isEnvEqual(a: PoolOptions['env'], b: PoolTask['env']) { - const keys = Object.keys(a) - - if (keys.length !== Object.keys(b).length) { - return false - } - - return keys.every(key => a[key] === b[key]) -} diff --git a/packages/vitest/src/node/pools/types.ts b/packages/vitest/src/node/pools/types.ts index 80b65c9d3418..ea805fc86c4f 100644 --- a/packages/vitest/src/node/pools/types.ts +++ b/packages/vitest/src/node/pools/types.ts @@ -13,13 +13,11 @@ export interface PoolOptions { cacheFs?: boolean environment: string execArgv: string[] - env: Record + env: Partial } export interface PoolWorker { readonly name: string - readonly execArgv: string[] - readonly env: Record readonly reportMemory?: boolean readonly cacheFs?: boolean @@ -30,13 +28,20 @@ export interface PoolWorker { start: () => Promise stop: () => Promise + + /** + * This is called on workers that already satisfy certain constraints: + * - The task has the same project + * - The task has the same environment + */ + canReuse?: (task: PoolTask) => boolean } export interface PoolTask { worker: 'forks' | 'threads' | 'vmForks' | 'vmThreads' | (string & {}) project: TestProject isolate: boolean - env: Record + env: Partial execArgv: string[] context: ContextRPC memoryLimit: number | null diff --git a/packages/vitest/src/node/pools/workers/forksWorker.ts b/packages/vitest/src/node/pools/workers/forksWorker.ts index 6b8e3a71decf..e98c5e14aafa 100644 --- a/packages/vitest/src/node/pools/workers/forksWorker.ts +++ b/packages/vitest/src/node/pools/workers/forksWorker.ts @@ -10,11 +10,11 @@ const SIGKILL_TIMEOUT = 500 /** jest does 500ms by default, let's follow it */ /** @experimental */ export class ForksPoolWorker implements PoolWorker { public readonly name: string = 'forks' - public readonly execArgv: string[] - public readonly env: Record public readonly cacheFs: boolean = true protected readonly entrypoint: string + protected execArgv: string[] + protected env: Partial private _fork?: ChildProcess diff --git a/packages/vitest/src/node/pools/workers/threadsWorker.ts b/packages/vitest/src/node/pools/workers/threadsWorker.ts index 32c45106f66e..c3816a61473a 100644 --- a/packages/vitest/src/node/pools/workers/threadsWorker.ts +++ b/packages/vitest/src/node/pools/workers/threadsWorker.ts @@ -5,9 +5,10 @@ import { Worker } from 'node:worker_threads' /** @experimental */ export class ThreadsPoolWorker implements PoolWorker { public readonly name: string = 'threads' - public readonly execArgv: string[] - public readonly env: Record + protected readonly entrypoint: string + protected execArgv: string[] + protected env: Partial private _thread?: Worker diff --git a/packages/vitest/src/node/pools/workers/typecheckWorker.ts b/packages/vitest/src/node/pools/workers/typecheckWorker.ts index 5ee36862687b..f71cd0ec1316 100644 --- a/packages/vitest/src/node/pools/workers/typecheckWorker.ts +++ b/packages/vitest/src/node/pools/workers/typecheckWorker.ts @@ -13,15 +13,11 @@ import { Typechecker } from '../../../typecheck/typechecker' /** @experimental */ export class TypecheckPoolWorker implements PoolWorker { public readonly name: string = 'typecheck' - public readonly execArgv: string[] - public readonly env: Record private readonly project: TestProject private _eventEmitter = new EventEmitter() constructor(options: PoolOptions) { - this.execArgv = options.execArgv - this.env = options.env this.project = options.project } @@ -33,6 +29,10 @@ export class TypecheckPoolWorker implements PoolWorker { // noop, onMessage handles it } + canReuse(): boolean { + return true + } + send(message: WorkerRequest): void { void onMessage(message, this.project).then((response) => { if (response) { diff --git a/packages/vitest/src/node/pools/workers/vmForksWorker.ts b/packages/vitest/src/node/pools/workers/vmForksWorker.ts index 2cc5c8d2e870..a2e5a6700abf 100644 --- a/packages/vitest/src/node/pools/workers/vmForksWorker.ts +++ b/packages/vitest/src/node/pools/workers/vmForksWorker.ts @@ -9,7 +9,8 @@ export class VmForksPoolWorker extends ForksPoolWorker { protected readonly entrypoint: string constructor(options: PoolOptions) { - super({ ...options, execArgv: [...options.execArgv, '--experimental-vm-modules'] }) + super(options) + this.execArgv.push('--experimental-vm-modules') /** Loads {@link file://./../../../runtime/workers/vmForks.ts} */ this.entrypoint = resolve(options.distPath, 'workers/vmForks.js') diff --git a/packages/vitest/src/node/pools/workers/vmThreadsWorker.ts b/packages/vitest/src/node/pools/workers/vmThreadsWorker.ts index 779e45b3be67..cf66dacae36d 100644 --- a/packages/vitest/src/node/pools/workers/vmThreadsWorker.ts +++ b/packages/vitest/src/node/pools/workers/vmThreadsWorker.ts @@ -9,7 +9,8 @@ export class VmThreadsPoolWorker extends ThreadsPoolWorker { protected readonly entrypoint: string constructor(options: PoolOptions) { - super({ ...options, execArgv: [...options.execArgv, '--experimental-vm-modules'] }) + super(options) + this.execArgv.push('--experimental-vm-modules') /** Loads {@link file://./../../../runtime/workers/vmThreads.ts} */ this.entrypoint = resolve(options.distPath, 'workers/vmThreads.js') diff --git a/test/cli/fixtures/custom-pool/pool/custom-pool.ts b/test/cli/fixtures/custom-pool/pool/custom-pool.ts index e91fa79a1f8b..2e241cb3b2e9 100644 --- a/test/cli/fixtures/custom-pool/pool/custom-pool.ts +++ b/test/cli/fixtures/custom-pool/pool/custom-pool.ts @@ -20,13 +20,9 @@ export class CustomRuntimeWorker implements PoolWorker { public readonly name = 'custom' private vitest: Vitest private customEvents = new EventEmitter() - readonly execArgv: string[] - readonly env: Record private project: TestProject constructor(options: PoolOptions, private settings: OptionsCustomPool) { - this.execArgv = options.execArgv - this.env = options.env this.vitest = options.project.vitest this.project = options.project }