Skip to content

test: fix dangling promise in test_runner no isolation test setup #57595

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

JakobJingleheimer
Copy link
Member

@JakobJingleheimer JakobJingleheimer commented Mar 22, 2025

The --imported / --required file contained an un-awaited dynamic import, so it's subsequent code was not guaranteed to finish before the entry-point starts. Strangely that should have caused this test to fail some times, but it seems to be consistently fast enough so that the race condition doesn't occur.

I checked with the original author of the test, and this was not intended (it was only done that way in an attempt to simplify setup and recycle fixtures).

However, after speed improvements in #57419, the race condition was exposed and does occur consistently (causing the global hooks to get registered out of their intended/expected sequence).

@JakobJingleheimer JakobJingleheimer added the test_runner Issues and PRs related to the test runner subsystem. label Mar 22, 2025
@nodejs-github-bot
Copy link
Collaborator

Review requested:

  • @nodejs/test_runner

@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. test Issues and PRs related to the tests. labels Mar 22, 2025
@JakobJingleheimer
Copy link
Member Author

The test is passing on the --import case but failing for the --require case (red lines are missing in actual vs expected):

before(): global
before one: <root>
suite one
before two: <root>
suite two
- beforeEach(): global
beforeEach one: suite one - test
beforeEach two: suite one - test
suite one - test
- afterEach(): global
afterEach one: suite one - test
afterEach two: suite one - test
before suite two: suite two
- beforeEach(): global
beforeEach one: suite two - test
beforeEach two: suite two - test
suite two - test
- afterEach(): global
afterEach one: suite two - test
afterEach two: suite two - test
- after(): global
after one: <root>
after two: <root>

@avivkeller and I did some digging, and they've summarised our findings over here (but let's keep the discussion of it to this PR) #57419 (comment).

Copy link

codecov bot commented Mar 23, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 90.25%. Comparing base (a4f556f) to head (aee5b62).
Report is 30 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main   #57595   +/-   ##
=======================================
  Coverage   90.24%   90.25%           
=======================================
  Files         630      630           
  Lines      185129   185074   -55     
  Branches    36238    36220   -18     
=======================================
- Hits       167064   167030   -34     
+ Misses      11045    11024   -21     
  Partials     7020     7020           

see 34 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@@ -1,6 +0,0 @@
import('node:test').then((test) => {
Copy link
Member

Choose a reason for hiding this comment

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

can we add tests for both require and import in cjs?

Copy link
Member Author

Choose a reason for hiding this comment

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

There is already in this PR, no?

Copy link
Member

Choose a reason for hiding this comment

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

I might be missing it but where is there a cjs test with import?

Copy link
Member Author

@JakobJingleheimer JakobJingleheimer Mar 24, 2025

Choose a reason for hiding this comment

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

OH, sorry I think I misunderstood. You want

node --import  global.cjs test.js
node --require global.cjs test.js // this exists
node --import  global.mjs test.js // this exists

Copy link
Member Author

Choose a reason for hiding this comment

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

Done (and the import CJS case passes): 6a38d32

Copy link
Member Author

Choose a reason for hiding this comment

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

@MoLow 👀

Copy link
Member

Choose a reason for hiding this comment

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

@JakobJingleheimer if nobody precedes me, I'll take a look ASAP.

Copy link
Member Author

Choose a reason for hiding this comment

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

@pmarchini looks like nobody is, so if you could, that would be great 😀

Copy link
Member

@MoLow MoLow left a comment

Choose a reason for hiding this comment

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

tests seem to need an adjustment, but implementation LGTM

@JakobJingleheimer
Copy link
Member Author

tests seem to need an adjustment, but implementation LGTM

@MoLow hmm? could you advise what about the test needs adjusting? After fixing the dangling promise issue, it looks good to me 🤔 Since it affects only the --require case, I think it's a bug in that branch of the test runner code.

@MoLow
Copy link
Member

MoLow commented Apr 1, 2025

@JakobJingleheimer I was referring to the failing tests, not necessarily related to this change

@pmarchini
Copy link
Member

cc @JakobJingleheimer as per our discussion.

I checked and, unless I completely missed something, the cause is the following:

Because of the --require flag (which is executed before the root test is created by the test runner here:

function loadPreloadModules() {
), and considering that the module contains test runner hooks, a root test is created via lazy bootstrap.
This executes the before hook but no other hooks.
At this point, the test runner (due to the --test flag) creates a new root test, which, however, does not handle the --require flag.
For this reason, the behaviour is what we’re seeing.

Sure! Here's just the part you asked for:

Here's an example output with some added logs:

preloadModules: [...]/test/fixtures/test-runner/no-isolation/global-hooks.cjs <-- 
lazyBootstrapRoot <-- 
before(): global
Creating test tree <--
before one: <root>
suite one
before two: <root>
suite two
beforeEach one: suite one - test
beforeEach two: suite one - test
...

@JakobJingleheimer
Copy link
Member Author

Awesome! Thank you @pmarchini 🙏

In that case, this is an outstanding bug in the implementation, which I think is outside the scope of this PR and the others that are affected (blocked) by it. Since it's a bug that already exists and was discovered by fixing a test, I think it's acceptable to mark the failing test-case as an expected failure, and fix that subsequently. Thoughts @MoLow @pmarchini?

@pmarchini
Copy link
Member

@JakobJingleheimer +1 on my side, I'd suggest adding a todo comment about the root cause

Copy link
Member

@pmarchini pmarchini left a comment

Choose a reason for hiding this comment

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

LGTM

@JakobJingleheimer JakobJingleheimer added the request-ci Add this label to start a Jenkins CI on a PR. label Apr 2, 2025
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Apr 2, 2025
@nodejs-github-bot
Copy link
Collaborator

@pmarchini pmarchini requested a review from cjihrig April 2, 2025 14:08
@JakobJingleheimer JakobJingleheimer added commit-queue Add this label to land a pull request using GitHub Actions. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Apr 2, 2025
@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Apr 2, 2025
@nodejs-github-bot nodejs-github-bot merged commit 5a2614f into nodejs:main Apr 2, 2025
63 checks passed
@nodejs-github-bot
Copy link
Collaborator

Landed in 5a2614f

@JakobJingleheimer JakobJingleheimer deleted the test_runner/fix/dangling-promise-in-setup-file branch April 2, 2025 21:10
JonasBa pushed a commit to JonasBa/node that referenced this pull request Apr 11, 2025
PR-URL: nodejs#57595
Reviewed-By: Moshe Atlow <[email protected]>
Reviewed-By: Marco Ippolito <[email protected]>
Reviewed-By: Pietro Marchini <[email protected]>
RafaelGSS pushed a commit that referenced this pull request May 1, 2025
PR-URL: #57595
Reviewed-By: Moshe Atlow <[email protected]>
Reviewed-By: Marco Ippolito <[email protected]>
Reviewed-By: Pietro Marchini <[email protected]>
RafaelGSS pushed a commit that referenced this pull request May 2, 2025
PR-URL: #57595
Reviewed-By: Moshe Atlow <[email protected]>
Reviewed-By: Marco Ippolito <[email protected]>
Reviewed-By: Pietro Marchini <[email protected]>
aduh95 pushed a commit that referenced this pull request May 6, 2025
PR-URL: #57595
Reviewed-By: Moshe Atlow <[email protected]>
Reviewed-By: Marco Ippolito <[email protected]>
Reviewed-By: Pietro Marchini <[email protected]>
RafaelGSS pushed a commit that referenced this pull request May 14, 2025
PR-URL: #57595
Reviewed-By: Moshe Atlow <[email protected]>
Reviewed-By: Marco Ippolito <[email protected]>
Reviewed-By: Pietro Marchini <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. needs-ci PRs that need a full CI run. test_runner Issues and PRs related to the test runner subsystem. test Issues and PRs related to the tests.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants