Skip to content

Commit

Permalink
--logHeapUsage: also log process id
Browse files Browse the repository at this point in the history
This is meant to aid dealing with #11956

--logHeapUsage after each test logs the heap size of whatever worker
happened to run it, but because results are interleaved from multiple
workers, one has to guess which heap sizes came from different workers
(jest doesn't even log how many workers are involved).

=> This adds the process id:

    PASS src/BlaBla.test.ts (9.64 s, pid 1085066: 266 MB heap size)

Making it easy to focus on a single worker's heap history,
or plot each worker's progression separately:

    egrep --only-matching 'pid.*heap size' JEST_OUTPUT.txt |
      sort --field-separator=' ' --key=2 --numeric --stable

Printing OS process ids also allows correlating with other perf tools like `top`.
It also reflects workers getting shutdown/replaced with `--workerIdleMemoryLimit`:

    PASS __tests__/test1.js (pid 1104509: 22 MB heap size)
    PASS __tests__/test2.js (pid 1104519: 22 MB heap size)
    PASS __tests__/test3.js (pid 1104529: 22 MB heap size)
  • Loading branch information
cben committed Aug 15, 2023
1 parent 25a8785 commit c3516b6
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 3 deletions.
9 changes: 9 additions & 0 deletions e2e/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,15 @@ export const extractSummaries = (
.map(({start, end}) => extractSortedSummary(stdout.slice(start, end)));
};

/** Only works in --logHeapUsage mode. */
export const extractWorkerPids = (stdout: string) => {
const processIds = new Set<string>();
for (const groups of stdout.matchAll(/(?:PASS|FAIL) .*pid (\d+)/gm)) {
processIds.add(groups[1]);
}
return processIds;
};

// Certain environments (like CITGM and GH Actions) do not come with mercurial installed
let hgIsInstalled: boolean | null = null;

Expand Down
4 changes: 3 additions & 1 deletion e2e/__tests__/logHeapUsage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@ test('logs memory usage', () => {
});

const {stderr} = runJest(DIR, ['--logHeapUsage']);
expect(stderr).toMatch(/PASS\s__tests__\/a-banana.js.*\d+ MB heap size/);
expect(stderr).toMatch(
/PASS\s__tests__\/a-banana.js.*pid \d+: \d+ MB heap size/,
);
});
16 changes: 15 additions & 1 deletion e2e/__tests__/workerRestarting.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/

import {extractSummary} from '../Utils';
import {extractSummary, extractWorkerPids} from '../Utils';
import runJest from '../runJest';

it('all 3 test files should complete', () => {
Expand All @@ -14,3 +14,17 @@ it('all 3 test files should complete', () => {
const {summary} = extractSummary(result.stderr);
expect(summary).toMatchSnapshot();
});

it('3 different worker processes should get used', () => {
const result = runJest('worker-restarting', ['--logHeapUsage']);
const processIds = extractWorkerPids(result.stderr);
expect([...processIds]).toHaveLength(3);
});

it('2 worker processes should be kept with high limit', () => {
// This could get flaky if memory usage on tiny test becomes much worse,
// but that'd be good to notice ;-). As of this writing, I've seen 20-43 MB.
const result = runJest('worker-not-restarting', ['--logHeapUsage']);
const processIds = extractWorkerPids(result.stderr);
expect([...processIds]).toHaveLength(2);
});
10 changes: 10 additions & 0 deletions e2e/worker-not-restarting/__tests__/test1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

test('basic test', () => {
expect(true).toBeTruthy();
});
10 changes: 10 additions & 0 deletions e2e/worker-not-restarting/__tests__/test2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

test('basic test', () => {
expect(true).toBeTruthy();
});
10 changes: 10 additions & 0 deletions e2e/worker-not-restarting/__tests__/test3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

test('basic test', () => {
expect(true).toBeTruthy();
});
6 changes: 6 additions & 0 deletions e2e/worker-not-restarting/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"jest": {
"maxWorkers": 2,
"workerIdleMemoryLimit": "200MB"
}
}
4 changes: 3 additions & 1 deletion packages/jest-reporters/src/getResultHeader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ export default function getResultHeader(

if (result.memoryUsage) {
const toMB = (bytes: number) => Math.floor(bytes / 1024 / 1024);
testDetail.push(`${toMB(result.memoryUsage)} MB heap size`);
testDetail.push(
`pid ${result.workerProcessId}: ${toMB(result.memoryUsage)} MB heap size`

Check failure on line 49 in packages/jest-reporters/src/getResultHeader.ts

View workflow job for this annotation

GitHub Actions / Lint

Insert `,`
);
}

const projectDisplayName =
Expand Down
1 change: 1 addition & 0 deletions packages/jest-runner/src/runTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ async function runTestInternal(
result.console = testConsole.getBuffer();
result.skipped = testCount === result.numPendingTests;
result.displayName = projectConfig.displayName;
result.workerProcessId = process.pid;

const coverage = runtime.getAllCoverageInfoCopy();
if (coverage) {
Expand Down
1 change: 1 addition & 0 deletions packages/jest-test-result/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ export type TestResult = {
failureMessage?: string | null;
leaks: boolean;
memoryUsage?: number;
workerProcessId?: number;
numFailingTests: number;
numPassingTests: number;
numPendingTests: number;
Expand Down

0 comments on commit c3516b6

Please sign in to comment.