(vitest: Vitest)
| 18 | const debug = createDebugger('vitest:browser:pool') |
| 19 | |
| 20 | export function createBrowserPool(vitest: Vitest): ProcessPool { |
| 21 | const providers = new Set<BrowserProvider>() |
| 22 | |
| 23 | const numCpus |
| 24 | = typeof nodeos.availableParallelism === 'function' |
| 25 | ? nodeos.availableParallelism() |
| 26 | : nodeos.cpus().length |
| 27 | |
| 28 | // if there are more than ~12 threads (optimistically), the main thread chokes |
| 29 | // https://github.com/vitest-dev/vitest/issues/7871 |
| 30 | const maxThreadsCount = Math.min(12, numCpus - 1) |
| 31 | const threadsCount = vitest.config.watch |
| 32 | ? Math.max(Math.floor(maxThreadsCount / 2), 1) |
| 33 | : Math.max(maxThreadsCount, 1) |
| 34 | |
| 35 | const projectPools = new WeakMap<TestProject, BrowserPool>() |
| 36 | |
| 37 | const ensurePool = (project: TestProject) => { |
| 38 | if (projectPools.has(project)) { |
| 39 | return projectPools.get(project)! |
| 40 | } |
| 41 | |
| 42 | debug?.('creating pool for project %s', project.name) |
| 43 | |
| 44 | const pool: BrowserPool = new BrowserPool(project, { |
| 45 | maxWorkers: getThreadsCount(project), |
| 46 | }) |
| 47 | projectPools.set(project, pool) |
| 48 | vitest.onCancel(() => { |
| 49 | pool.cancel() |
| 50 | }) |
| 51 | |
| 52 | return pool |
| 53 | } |
| 54 | |
| 55 | const runWorkspaceTests = async (method: 'run' | 'collect', specs: TestSpecification[]) => { |
| 56 | const groupedFiles = new Map<TestProject, FileSpecification[]>() |
| 57 | const testFilesCode = new Map<string, string>() |
| 58 | const testFileTags = new WeakMap<TestSpecification, string[]>() |
| 59 | |
| 60 | await Promise.all(specs.map(async (spec) => { |
| 61 | let code = testFilesCode.get(spec.moduleId) |
| 62 | // TODO: this really should be done only once when collecting specifications |
| 63 | if (code == null) { |
| 64 | code = await readFile(spec.moduleId, 'utf-8').catch(() => '') |
| 65 | testFilesCode.set(spec.moduleId, code) |
| 66 | } |
| 67 | const { tags } = detectCodeBlock(code) |
| 68 | testFileTags.set(spec, tags) |
| 69 | })) |
| 70 | |
| 71 | // to keep the sorting, we need to iterate over specs separately |
| 72 | for (const spec of specs) { |
| 73 | const { project, moduleId, testLines, testIds, testNamePattern, testTagsFilter } = spec |
| 74 | const files = groupedFiles.get(project) || [] |
| 75 | files.push({ |
| 76 | filepath: moduleId, |
| 77 | testLocations: testLines, |
no test coverage detected