| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -151,8 +151,8 @@ export function createPool(ctx: Vitest): ProcessPool { | |||
| 151 | 151 | invalidates, | |
| 152 | 152 | providedContext: project.getProvidedContext(), | |
| 153 | 153 | workerId: workerId++, | |
| 154 | + environment, | ||
| 154 | 155 | }, | |
| 155 | - environment, | ||
| 156 | 156 | project, | |
| 157 | 157 | env, | |
| 158 | 158 | execArgv, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,3 +1,4 @@ | |||
| 1 | + import type { ContextTestEnvironment } from '../../types/worker' | ||
| 1 | 2 | import type { Logger } from '../logger' | |
| 2 | 3 | import type { StateManager } from '../state' | |
| 3 | 4 | import type { PoolOptions, PoolTask, WorkerResponse } from './types' | |
@@ -213,15 +214,17 @@ export class Pool { | |||
| 213 | 214 | const index = this.sharedRunners.findIndex(runner => isEqualRunner(runner, task)) | |
| 214 | 215 | ||
| 215 | 216 | if (index !== -1) { | |
| 216 | - return this.sharedRunners.splice(index, 1)[0] | ||
| 217 | + const runner = this.sharedRunners.splice(index, 1)[0] | ||
| 218 | + runner.reconfigure(task) | ||
| 219 | + return runner | ||
| 217 | 220 | } | |
| 218 | 221 | } | |
| 219 | 222 | ||
| 220 | 223 | const options: PoolOptions = { | |
| 221 | 224 | distPath: this.options.distPath, | |
| 222 | 225 | project: task.project, | |
| 223 | 226 | method, | |
| 224 | - environment: task.environment, | ||
| 227 | + environment: task.context.environment, | ||
| 225 | 228 | env: task.env, | |
| 226 | 229 | execArgv: task.execArgv, | |
| 227 | 230 | } | |
@@ -289,11 +292,47 @@ function isEqualRunner(runner: PoolRunner, task: PoolTask) { | |||
| 289 | 292 | if (task.isolate) { | |
| 290 | 293 | throw new Error('Isolated tasks should not share runners') | |
| 291 | 294 | } | |
| 295 | + if (runner.worker.name !== task.worker || runner.project !== task.project) { | ||
| 296 | + return false | ||
| 297 | + } | ||
| 298 | + // by default, check that the environments are the same | ||
| 299 | + // some workers (like vmThreads/vmForks) do not need this check | ||
| 300 | + if (!runner.worker.canReuse) { | ||
| 301 | + return isEnvironmentEqual(task.context.environment, runner.environment) | ||
| 302 | + } | ||
| 303 | + return runner.worker.canReuse(task) | ||
| 304 | + } | ||
| 305 | + | ||
| 306 | + function isEnvironmentEqual(env1: ContextTestEnvironment, env2: ContextTestEnvironment): boolean { | ||
| 307 | + if (env1.name !== env2.name) { | ||
| 308 | + return false | ||
| 309 | + } | ||
| 310 | + return deepEqual(env1.options, env2.options) | ||
| 311 | + } | ||
| 312 | + | ||
| 313 | + function deepEqual(obj1: any, obj2: any): boolean { | ||
| 314 | + if (obj1 === obj2) { | ||
| 315 | + return true | ||
| 316 | + } | ||
| 317 | + if (obj1 == null || obj2 == null) { | ||
| 318 | + return obj1 === obj2 | ||
| 319 | + } | ||
| 320 | + if (typeof obj1 !== 'object' || typeof obj2 !== 'object') { | ||
| 321 | + return false | ||
| 322 | + } | ||
| 323 | + | ||
| 324 | + const keys1 = Object.keys(obj1) | ||
| 325 | + const keys2 = Object.keys(obj2) | ||
| 326 | + | ||
| 327 | + if (keys1.length !== keys2.length) { | ||
| 328 | + return false | ||
| 329 | + } | ||
| 330 | + | ||
| 331 | + for (const key of keys1) { | ||
| 332 | + if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) { | ||
| 333 | + return false | ||
| 334 | + } | ||
| 335 | + } | ||
| 292 | 336 | ||
| 293 | - return ( | ||
| 294 | - runner.worker.name === task.worker | ||
| 295 | - && runner.project === task.project | ||
| 296 | - && runner.environment.name === task.environment.name | ||
| 297 | - && (!runner.worker.canReuse || runner.worker.canReuse(task)) | ||
| 298 | - ) | ||
| 337 | + return true | ||
| 299 | 338 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,7 +5,7 @@ import type { RunnerRPC, RuntimeRPC } from '../../types/rpc' | |||
| 5 | 5 | import type { ContextTestEnvironment, WorkerExecuteContext } from '../../types/worker' | |
| 6 | 6 | import type { Traces } from '../../utils/traces' | |
| 7 | 7 | import type { TestProject } from '../project' | |
| 8 | - import type { PoolOptions, PoolRunnerOTEL, PoolWorker, WorkerRequest, WorkerResponse } from './types' | ||
| 8 | + import type { PoolOptions, PoolRunnerOTEL, PoolTask, PoolWorker, WorkerRequest, WorkerResponse } from './types' | ||
| 9 | 9 | import { EventEmitter } from 'node:events' | |
| 10 | 10 | import { createDefer } from '@vitest/utils/helpers' | |
| 11 | 11 | import { createBirpc } from 'birpc' | |
@@ -43,7 +43,7 @@ export class PoolRunner { | |||
| 43 | 43 | public poolId: number | undefined = undefined | |
| 44 | 44 | ||
| 45 | 45 | public readonly project: TestProject | |
| 46 | - public readonly environment: ContextTestEnvironment | ||
| 46 | + public environment: ContextTestEnvironment | ||
| 47 | 47 | ||
| 48 | 48 | private _state: RunnerState = RunnerState.IDLE | |
| 49 | 49 | private _operationLock: DeferPromise<void> | null = null | |
@@ -113,6 +113,15 @@ export class PoolRunner { | |||
| 113 | 113 | this._offCancel = vitest.onCancel(reason => this._rpc.onCancel(reason)) | |
| 114 | 114 | } | |
| 115 | 115 | ||
| 116 | + /** | ||
| 117 | + * "reconfigure" can only be called if `environment` is different, since different project always | ||
| 118 | + * requires a new PoolRunner instance. | ||
| 119 | + */ | ||
| 120 | + public reconfigure(task: PoolTask): void { | ||
| 121 | + this.environment = task.context.environment | ||
| 122 | + this._otel?.span.setAttribute('vitest.environment', this.environment.name) | ||
| 123 | + } | ||
| 124 | + | ||
| 116 | 125 | postMessage(message: WorkerRequest): void { | |
| 117 | 126 | // Only send messages when runner is active (not fully stopped) | |
| 118 | 127 | // Allow sending during STOPPING state for the 'stop' message itself | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -34,8 +34,8 @@ export interface PoolWorker { | |||
| 34 | 34 | ||
| 35 | 35 | /** | |
| 36 | 36 | * This is called on workers that already satisfy certain constraints: | |
| 37 | + * - The task has the same worker name | ||
| 37 | 38 | * - The task has the same project | |
| 38 | - * - The task has the same environment | ||
| 39 | 39 | */ | |
| 40 | 40 | canReuse?: (task: PoolTask) => boolean | |
| 41 | 41 | } | |
@@ -55,7 +55,6 @@ export interface PoolTask { | |||
| 55 | 55 | */ | |
| 56 | 56 | execArgv: string[] | |
| 57 | 57 | context: WorkerExecuteContext | |
| 58 | - environment: ContextTestEnvironment | ||
| 59 | 58 | memoryLimit: number | null | |
| 60 | 59 | } | |
| 61 | 60 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,4 +14,8 @@ export class VmForksPoolWorker extends ForksPoolWorker { | |||
| 14 | 14 | /** Loads {@link file://./../../../runtime/workers/vmForks.ts} */ | |
| 15 | 15 | this.entrypoint = resolve(options.distPath, 'workers/vmForks.js') | |
| 16 | 16 | } | |
| 17 | + | ||
| 18 | + canReuse(): boolean { | ||
| 19 | + return true | ||
| 20 | + } | ||
| 17 | 21 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -14,4 +14,8 @@ export class VmThreadsPoolWorker extends ThreadsPoolWorker { | |||
| 14 | 14 | /** Loads {@link file://./../../../runtime/workers/vmThreads.ts} */ | |
| 15 | 15 | this.entrypoint = resolve(options.distPath, 'workers/vmThreads.js') | |
| 16 | 16 | } | |
| 17 | + | ||
| 18 | + canReuse(): boolean { | ||
| 19 | + return true | ||
| 20 | + } | ||
| 17 | 21 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -24,6 +24,7 @@ export interface WorkerExecuteContext { | |||
| 24 | 24 | files: FileSpecification[] | |
| 25 | 25 | providedContext: Record<string, any> | |
| 26 | 26 | invalidates?: string[] | |
| 27 | + environment: ContextTestEnvironment | ||
| 27 | 28 | ||
| 28 | 29 | /** Exposed to test runner as `VITEST_WORKER_ID`. Value is unique per each isolated worker. */ | |
| 29 | 30 | workerId: number | |
| Back | FazBrowse Home | New Git URL |
0 commit comments