Skip to content

Commit

Permalink
feat: make worker count configurable
Browse files Browse the repository at this point in the history
Signed-off-by: Chapman Pendery <[email protected]>
  • Loading branch information
cpendery committed Mar 6, 2024
1 parent 1cba29f commit 8d2a5ea
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 20 deletions.
23 changes: 23 additions & 0 deletions src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import fs from "node:fs";
import path from "node:path";
import process from "node:process";
import os from "node:os";

import { defaultShell } from "../terminal/shell.js";
import { TestOptions } from "../test/option.js";
Expand All @@ -26,6 +27,10 @@ export const loadConfig = async (): Promise<Required<TestConfig>> => {
projects: userConfig.projects ?? [],
timeout: userConfig.timeout ?? 30_000,
reporter: userConfig.reporter ?? "list",
workers: Math.max(
userConfig.workers ?? Math.max(Math.floor(os.cpus().length / 2), 1),
1
),
use: {
shell: userConfig.use?.shell ?? defaultShell,
rows: userConfig.use?.rows ?? 30,
Expand Down Expand Up @@ -197,6 +202,24 @@ export declare type TestConfig = {
*/
use?: TestOptions;

/**
* The number of workers to use. Defaults to 50% of the logical cpu cores. If
* there are less tests than requested workers, there will be 1 worker used per test.
*
* **Usage**
*
* ```js
* // tui-test.config.ts
* import { defineConfig } from '@microsoft/tui-test';
*
* export default defineConfig({
* workers: 4,
* });
* ```
*
*/
workers?: number;

/**
* TUI Test supports running multiple test projects at the same time.
*
Expand Down
7 changes: 5 additions & 2 deletions src/reporter/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { TestCase, TestResult, TestStatus } from "../test/testcase.js";
import { Shell } from "../terminal/shell.js";
import { loadShellVersions } from "./utils.js";
import { Suite } from "../test/suite.js";
import { maxWorkers } from "../runner/runner.js";

type TestSummary = {
didNotRun: number;
Expand Down Expand Up @@ -44,7 +43,11 @@ export class BaseReporter {
return `${text}${count > 1 ? "s" : ""}`;
}

async start(testCount: number, shells: Shell[]): Promise<void> {
async start(
testCount: number,
shells: Shell[],
maxWorkers: number
): Promise<void> {
const shellVersions = await loadShellVersions(shells);
const workers = Math.min(testCount, maxWorkers);
process.stdout.write(
Expand Down
8 changes: 6 additions & 2 deletions src/reporter/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ export class ListReporter extends BaseReporter {
this._testRows = {};
}

override async start(testCount: number, shells: Shell[]): Promise<void> {
await super.start(testCount, shells);
override async start(
testCount: number,
shells: Shell[],
maxWorkers: number
): Promise<void> {
await super.start(testCount, shells, maxWorkers);
}

override startTest(test: TestCase, result: TestResult): void {
Expand Down
37 changes: 21 additions & 16 deletions src/runner/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import path from "node:path";
import url from "node:url";
import os from "node:os";
import workerpool from "workerpool";
import workerpool, { Pool } from "workerpool";
import chalk from "chalk";

import { Suite, getRootSuite } from "../test/suite.js";
Expand Down Expand Up @@ -32,25 +32,28 @@ type ExecutionOptions = {
};

const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
export const maxWorkers = Math.max(Math.floor(os.cpus().length / 2), 1);
const pool = workerpool.pool(path.join(__dirname, "worker.js"), {
workerType: "process",
maxWorkers,
forkOpts: {
stdio: "inherit",
env: {
...process.env,
...(supportsColor ? { FORCE_COLOR: "1" } : {}),

const createWorkerPool = (maxWorkers: number): Pool => {
return workerpool.pool(path.join(__dirname, "worker.js"), {
workerType: "process",
maxWorkers,
forkOpts: {
stdio: "inherit",
env: {
...process.env,
...(supportsColor ? { FORCE_COLOR: "1" } : {}),
},
},
},
emitStdStreams: true,
});
emitStdStreams: true,
});
};

const runSuites = async (
allSuites: Suite[],
filteredTestIds: Set<string>,
reporter: BaseReporter,
{ updateSnapshot }: ExecutionOptions
{ updateSnapshot }: ExecutionOptions,
pool: Pool
) => {
const tasks: Promise<void>[] = [];
const suites = [...allSuites];
Expand Down Expand Up @@ -161,6 +164,7 @@ export const run = async (options: ExecutionOptions) => {
const config = await loadConfig();
const rootSuite = await getRootSuite(config);
const reporter = new ListReporter();
const pool = createWorkerPool(config.workers);

const suites = [rootSuite];
while (suites.length != 0) {
Expand Down Expand Up @@ -217,7 +221,7 @@ export const run = async (options: ExecutionOptions) => {
if (shells.includes(Shell.Zsh)) {
await setupZshDotfiles();
}
await reporter.start(allTests.length, shells);
await reporter.start(allTests.length, shells, config.workers);

if (config.globalTimeout > 0) {
setTimeout(() => {
Expand All @@ -232,7 +236,8 @@ export const run = async (options: ExecutionOptions) => {
rootSuite.suites,
new Set(allTests.map((test) => test.id)),
reporter,
options
options,
pool
);
try {
await pool.terminate(true);
Expand Down

0 comments on commit 8d2a5ea

Please sign in to comment.