Skip to content

test_runner: introduce NODE_TEST_WORKER_ID for improved concurrent te… - #56091

Closed
0hmX wants to merge 1 commit into
nodejs:mainfrom
0hmX:55842
Closed

test_runner: introduce NODE_TEST_WORKER_ID for improved concurrent te…#56091
0hmX wants to merge 1 commit into
nodejs:mainfrom
0hmX:55842

Conversation

@0hmX

@0hmX0hmX commented Nov 30, 2024

Copy link
Copy Markdown
Contributor

ref: #55842

Added a new environment variable, NODE_TEST_WORKER_ID, which ranges from 1 to N when --experimental-test-isolation=process is enabled and defaults to 1 when --experimental-test-isolation=none is used.

Before merging, I want to add some tests but haven't come up with a good approach yet. Here's what I aim to test:

  • When --experimental-test-isolation=process is enabled, verify that NODE_TEST_WORKER_ID ranges from 1 to N.
  • When --experimental-test-isolation=none is used, ensure that NODE_TEST_WORKER_ID is set to 1.

Any suggestions on how to create such tests would be greatly appreciated!

@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Review requested:

  • @nodejs/test_runner

@nodejs-github-botnodejs-github-bot added needs-ci PRs that need a full CI run. test_runner Issues and PRs related to the test runner subsystem. labels Nov 30, 2024

@mcollinamcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@pmarchinipmarchini left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @cu8code, thanks for the PR.
I'm requesting changes since we're still missing tests.
Regarding the implementation, LGTM.

Another important thing: to make this new feature available to users, we also need to update the documentation with this behavior 🚀

@JakobJingleheimer

Copy link
Copy Markdown
Member

Regarding the tests, I think you'll want to use spawnPromisified. See test-cjs-esm-warn.js

@JakobJingleheimer

JakobJingleheimer commented Dec 1, 2024

Copy link
Copy Markdown
Member

I'm concerned this has too much cross-over with threadId, for which the lack of sequentiality guarantee is likely reasoned—sequentiality likely would have been trivial to facilitate. I don't know who within our collaborators has that context though (maybe Anna?).

If there is a good reason behind making threadId non-sequential, I suspect this will be subject to that same rationale.

If there is not a particular rationale for the non-sequentiality of threadId, perhaps it would be better to guarantee that instead of creating a quasi-redundant mechanism.

The problem described in the cited issue is well handled via threadId when a complementary design is applied (which, IMO, is better than the attempted design the OP is trying to facilitate—which may well have been necessary in the environment in which it was created).

If we're merely trying to facilitate migration, I think we should first consider that point and whether there is a way to ease that migration without redundancy.

Without seeing the OP's code, I can only imagine what it looks like, but I suspect perhaps less than 20% would need to be adjusted. Likely the biggest hindrance is knowledge, which can be provided (ex a Learn article).

@0hmX

0hmX commented Dec 5, 2024

Copy link
Copy Markdown
ContributorAuthor

@JakobJingleheimer Thanks for helping with the test creation!
@pmarchini I've added the test and updated the documentation—please take a look when you have a chance.

@cjihrigcjihrig left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left a few comments. Have you verified that this works with watch mode (particularly watch mode + process isolation)?

Comment threaddoc/api/test.md Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be documented in doc/api/cli.md instead.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove this line. If things get moved around, this will almost certainly be forgotten about.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a newline at the end of the file.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename the directory from NODE_TEST_WORKER_ID to worker-id.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cu8code this still needs to be addressed 😁

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same comments apply to this file.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same comments apply to this file.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think three files is enough for this. I would drop this file.

Comment threadtest/parallel/test-runner-cli.js Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please move these new tests to a new file - test/parallel/test-runner-worker-id.js.

@0hmX

0hmX commented Dec 5, 2024

Copy link
Copy Markdown
ContributorAuthor

(particularly watch mode + process isolation)?

yes I have tested, its working fine! both for process and none

@0hmX
0hmXforce-pushed the 55842 branch 2 times, most recently from c722258 to 391e805CompareDecember 5, 2024 17:15
@0hmX

0hmX commented Dec 5, 2024

Copy link
Copy Markdown
ContributorAuthor

@cjihrig I’ve made the updates you requested. Please take a moment to review them!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please implement the tests using node:test ?
Here is an example : https://github.com/nodejs/node/blob/main/test/parallel/test-runner-run.mjs

@pmarchini

Copy link
Copy Markdown
Member

(particularly watch mode + process isolation)?

yes I have tested, its working fine! both for process and none

Hey @cu8code, regarding this: could you please also add some tests?

Comment threadtest/fixtures/test-runner/NODE_TEST_WORKER_ID/1.test.js Outdated
Comment threaddoc/api/cli.md Outdated
Comment threaddoc/api/cli.md Outdated
…st execution
Added a new environment variable, `NODE_TEST_WORKER_ID`, which ranges from 1 to N when `--experimental-test-isolation=process` is enabled and defaults to 1 when `--experimental-test-isolation=none` is used.
@0hmX

0hmX commented Dec 5, 2024

Copy link
Copy Markdown
ContributorAuthor

🤟 @cjihrig@pmarchini review

});


test('testing with isolation enabled in watch mode', async () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The watch mode tests added here have at least two problems:

  1. They don't actually test watch mode beyond passing the --watch flag. To properly test watch mode, you have to trigger the restart functionality.
  2. These tests will almost certainly be flaky in the CI. Waiting for a second, killing the child process, and expecting it to have run successfully probably works locally, but the CI machines can be very slow. I don't think we want to have a timeout at all.

I think these need to be refactored so that:

  • The test runs once.
  • Once the expected output is seen, a source file is modified (we don't want to modify the fixtures files directly either) to trigger a restart.
  • The test runs again. We need the output to be the same both times.

const fixtures = require('../common/fixtures');
const testFixtures = fixtures.path('test-runner');

test('testing with isolation enabled', () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I suggest being more expressive about what we are testing.

For example, describe('test runner worker-id'), followed by it('should set NODE_TEST_WORKER_ID in isolation x'), etc.

@rluvatonrluvaton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@codecov

codecovBot commented Dec 14, 2024

Copy link
Copy Markdown

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 87.99%. Comparing base (4ee87b8) to head (50ae060).
Report is 211 commits behind head on main.

Additional details and impacted files
@@ Coverage Diff @@## main #56091 +/- ##
==========================================
- Coverage 88.00% 87.99% -0.01% 
==========================================
Files 656 656 Lines 189000 189084 +84 Branches 35995 35991 -4 ==========================================
+ Hits 166320 166379 +59 - Misses 15840 15869 +29 + Partials 6840 6836 -4 
Files with missing linesCoverage Δ
lib/internal/test_runner/runner.js89.06% <100.00%> (+0.04%)⬆️

... and 53 files with indirect coverage changes

@pmarchini

Copy link
Copy Markdown
Member

Hey @cu8code, commit linter is failing, could you please fix it? ☺️

Comment threaddoc/api/cli.md
output will be sent to stdout in the TAP format. If any other value is provided,
Node.js makes no guarantees about the reporter format used or its stability.

### `NODE_TEST_WORKER_ID`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is the correct place for this. this is a list of env vars node accepts, not env vars it exposes

let workerId = 1;
return SafePromiseAllSettledReturnVoid(testFiles, (path) => {
const subtest = runTestFile(path, filesWatcher, opts);
const subtest = runTestFile(path, filesWatcher, opts, workerId);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if I have 8 cpus and 16 tests, I would expect each worker to be reused twice, but this implementation will not reuse worker ids, I think that is misleading

@cjihrig

Copy link
Copy Markdown
Contributor

@cu8code are you still working on this? If not, we should close this PR so that other folks can pick up the work.

@0hmX0hmX closed this Jan 6, 2025
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ciPRs that need a full CI run.test_runnerIssues and PRs related to the test runner subsystem.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants

@0hmX@nodejs-github-bot@JakobJingleheimer@pmarchini@cjihrig@mcollina@jasnell@MoLow@rluvaton