Skip to content
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

esm: improve performance & tidy tests #43784

Merged
merged 15 commits into from
Jul 29, 2022

Conversation

JakobJingleheimer
Copy link
Member

@JakobJingleheimer JakobJingleheimer commented Jul 11, 2022

This standardises the setup of ESM tests and improves performance by parallelising case runs using a promise wrapper around async spawn.

I originally started out using chaining for parallelisation, but switched to node:test to avoid a bajillion .then()s. As .then()s, the performance improvement was obvious.

I'm not sure how to get a truly apples-to-apples comparison: ./tools/test.py -J es-module doesn't benefit from node:test's parallelisation. I manually checked one of the largest tests, and the improvement is quite stark:

$> time ./node ./test/es-module/test-esm-loader-chaining.mjs
When Duration
Before 0m1.168s
After 0m0.442s

Note to reviewers: enabling Hide whitespace reduces the diff by about a third.

cc @nodejs/loaders

@JakobJingleheimer JakobJingleheimer added esm Issues and PRs related to the ECMAScript Modules implementation. loaders Issues and PRs related to ES module loaders labels Jul 11, 2022
@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 Jul 11, 2022
Copy link
Contributor

@aduh95 aduh95 left a comment

Choose a reason for hiding this comment

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

I would suggest to not refactor all the tests to ESM, that makes the PR needlessly harder to review, instead you can use dynamic import.

test/es-module/test-cjs-esm-warn.mjs Outdated Show resolved Hide resolved
@JakobJingleheimer
Copy link
Member Author

JakobJingleheimer commented Jul 11, 2022

@aduh95 I'm also hoping to standardise how the tests are written. Making them all ESM instead of a mix avoids someone wondering why some are one and others are another (there's no real reason—the CJS ones are just older).

How about I tackle that in a separate PR? I think if this lands first, then the CJS → ESM PR will have nothing to be reviewed.

PS My phone was sleeping when your comment came in, so I didn't see your message for the commit I just pushed.

@JakobJingleheimer JakobJingleheimer mentioned this pull request Jul 24, 2022
1 task
@JakobJingleheimer JakobJingleheimer force-pushed the esm/tidy-esm-tests branch 2 times, most recently from efb8000 to f3a2e1c Compare July 24, 2022 22:22
@JakobJingleheimer JakobJingleheimer marked this pull request as ready for review July 24, 2022 22:22
@JakobJingleheimer
Copy link
Member Author

There are some lint errors in the commonjs test files that I don't know how to fix:

node-core/require-common-first Mandatory module "common" must be loaded before any other modules

The files are already requiring common at the very top (immediately below 'use strict';),

node-core/async-iife-no-unused-result The result of an immediately-invoked async function needs to be used (e.g. with .then(common.mustCall()))

It's complaining about the (async () => {})() wrapper I added to the CJS tests in order to dynamic import the new spawnAsPromised helper.

@aduh95
Copy link
Contributor

aduh95 commented Jul 24, 2022

The files are already requiring common at the very top

It expects require('../common'), not require('../common/index.js').

It's complaining about the (async () => {})() wrapper I added to the CJS tests in order to dynamic import the new spawnAsPromised helper.

As the error message says, you need to use its result (i.e. add .then(common.mustCall())).

test/es-module/test-esm-cjs-load-error-note.mjs Outdated Show resolved Hide resolved
const { spawnSync } = require('child_process');
const fixture = fixtures.path('/es-modules/import-invalid-ext.mjs');
const child = spawnSync(process.execPath, [fixture]);
const errMsg = 'TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension';
Copy link
Member Author

Choose a reason for hiding this comment

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

This test is redundant to test/es-module/test-esm-unknown-or-no-extension.js

child.on('close', common.mustCall((code, signal) => {
assert.strictEqual(code, 1);
assert.strictEqual(signal, null);
(async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it be easier to refactor this to ESM to get TLA/static imports?

Copy link
Member Author

Choose a reason for hiding this comment

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

I did and you said to not, so I backed it out lol

Copy link
Contributor

Choose a reason for hiding this comment

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

The issue is that GitHub UI doesn't give an option to ignore the whitespace/indentation changes (I think?), if the only diff was adding the await import that would be much easier to review to keep it as CJS. As it is now, I doubt it makes much difference. Oh well, let's keep it as is, it can always be re-refactored later.

Copy link
Member

Choose a reason for hiding this comment

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

The issue is that GitHub UI doesn’t give an option to ignore the whitespace/indentation changes (I think?)

Add ?w=1 to the end of the URL. Or use one of the other methods: https://stackoverflow.com/a/37145215/223225.

Copy link
Member Author

Choose a reason for hiding this comment

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

"Hide whitespace" via the GitHub UI (on the file view screen):

image

Damn, sorry I had added a note to my PR description about hiding whitespace changes (it reduces the diff by 36%). I dunno what happened to that note 😖

Copy link
Member Author

Choose a reason for hiding this comment

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

🤦‍♂️ foiled by my own cleverness: who can spot the problem

image

Copy link
Member

Choose a reason for hiding this comment

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

Ah, that explains why I was never pinged about this 😄

test/es-module/test-esm-cjs-load-error-note.mjs Outdated Show resolved Hide resolved
test/es-module/test-esm-cjs-load-error-note.mjs Outdated Show resolved Hide resolved
test/es-module/test-esm-experimental-warnings.mjs Outdated Show resolved Hide resolved
test/es-module/test-esm-invalid-pjson.js Outdated Show resolved Hide resolved
test/es-module/test-esm-repl-imports.js Outdated Show resolved Hide resolved
test/es-module/test-esm-repl-imports.js Show resolved Hide resolved
Copy link
Member

@GeoffreyBooth GeoffreyBooth left a comment

Choose a reason for hiding this comment

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

This is too much to review with all the async function wrappers because of spawn. Please refactor that so that it has CommonJS and ESM versions available so that you can import it into all these CommonJS test files without needing to turn them into async functions, then I’ll re-review once the diff has shrunk.

test/es-module/helper.spawnAsPromised.mjs Outdated Show resolved Hide resolved
test/es-module/test-esm-cjs-load-error-note.mjs Outdated Show resolved Hide resolved
@JakobJingleheimer JakobJingleheimer deleted the esm/tidy-esm-tests branch July 31, 2022 18:36
@aduh95 aduh95 removed the test_runner Issues and PRs related to the test runner subsystem. label Jul 31, 2022
@targos
Copy link
Member

targos commented Aug 2, 2022

@GeoffreyBooth I assume you would like this to be included in a future v16.x release. The correct label for this is lts-watch-v16.x. Releasers/backporters will add backport-requested-v16.x if they have trouble cherry-picking the commit when a release is being prepared.

@GeoffreyBooth
Copy link
Member

@targos Sorry, thanks for the correction 😄 FYI this fixes a bug introduced by an earlier PR that hasn’t been released on 16 yet; see https://openjs-foundation.slack.com/archives/C01810KG1EF/p1659460515402819?thread_ts=1658853609.909249&cid=C01810KG1EF. @cspotcode will add a comment so that hopefully this fix goes out in the same release as the bug (so that the bug never actually gets released in 16.x).

@targos
Copy link
Member

targos commented Aug 2, 2022

@GeoffreyBooth There is a v16.x release proposal at #44098. This commit would normally not be eligible for inclusion in LTS because it's not been in a Current release yet. If there is a good reason to include it, please add a comment to #44098

@GeoffreyBooth
Copy link
Member

I think even better would be to just pull the commit that introduces the bug from the current release proposal, if it’s in there, and then that commit could go out in the same release as this one according to the usual schedule. (Waiting on which commit includes the bug.)

@JakobJingleheimer
Copy link
Member Author

Sorry, what bug does this fix?

@cspotcode
Copy link

I think there's a bit of confusion, this PR doesn't fix it, it's the thing you said you'd address in a PR after this PR lands. If everyone's ok waiting a few hours for me to post all the details, I can do that later today. Won't be able to right this moment.

@JakobJingleheimer
Copy link
Member Author

Ah, yes indeed. I shall put that bugfix together tomorrow (it's a simple fix). I wanted to wait for this to land to avoid a merge conflict in with the new test case for that bug.

targos pushed a commit that referenced this pull request Aug 6, 2022
PR-URL: #43784
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
danielleadams pushed a commit that referenced this pull request Aug 16, 2022
PR-URL: #43784
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
ruyadorno pushed a commit that referenced this pull request Aug 23, 2022
PR-URL: #43784
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
codebytere added a commit to electron/electron that referenced this pull request Aug 23, 2022
codebytere added a commit to electron/electron that referenced this pull request Aug 23, 2022
codebytere added a commit to electron/electron that referenced this pull request Aug 24, 2022
codebytere added a commit to electron/electron that referenced this pull request Aug 25, 2022
jkleinsc pushed a commit to electron/electron that referenced this pull request Aug 29, 2022
* chore: bump node in DEPS to v16.17.0

* chore: fixup asar patch

* lib: use null-prototype objects for property descriptors

nodejs/node#43270

* src: make SecureContext fields private

nodejs/node#43173

* crypto: remove Node.js-specific webcrypto extensions

nodejs/node#43310

* test: refactor to top-level await

nodejs/node#43500

* deps: cherry-pick two libuv fixes

nodejs/node#43950

* src: slim down env-inl.h

nodejs/node#43745

* util: add AggregateError.prototype.errors to inspect output

nodejs/node#43646

* esm: improve performance & tidy tests

nodejs/node#43784

* src: NodeArrayBufferAllocator delegates to v8's allocator

nodejs/node#43594

* chore: update patch indices

* chore: update filenames

* src: refactor IsSupportedAuthenticatedMode

nodejs/node#42368

* src: add --openssl-legacy-provider option

nodejs/node#40478

* lib,src: add source map support for global eval

nodejs/node#43428

* trace_events: trace net connect event

nodejs/node#43903

* deps: update ICU to 71.1

nodejs/node#42655

This fails the test because it's missing https://chromium-review.googlesource.com/c/chromium/deps/icu/+/3841093

* lib: give names to promisified exists() and question()

nodejs/node#43218

* crypto: add CFRG curves to Web Crypto API

nodejs/node#42507

* src: fix memory leak for v8.serialize

nodejs/node#42695

This test does not work for Electron as they do not use V8's
ArrayBufferAllocator.

* buffer: fix atob input validation

nodejs/node#42539

* src: fix ssize_t error from nghttp2.h

nodejs/node#44393

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Fyko pushed a commit to Fyko/node that referenced this pull request Sep 15, 2022
PR-URL: nodejs#43784
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
guangwong pushed a commit to noslate-project/node that referenced this pull request Oct 10, 2022
PR-URL: nodejs/node#43784
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
khalwa pushed a commit to solarwindscloud/electron that referenced this pull request Feb 22, 2023
* chore: bump node in DEPS to v16.17.0

* chore: fixup asar patch

* lib: use null-prototype objects for property descriptors

nodejs/node#43270

* src: make SecureContext fields private

nodejs/node#43173

* crypto: remove Node.js-specific webcrypto extensions

nodejs/node#43310

* test: refactor to top-level await

nodejs/node#43500

* deps: cherry-pick two libuv fixes

nodejs/node#43950

* src: slim down env-inl.h

nodejs/node#43745

* util: add AggregateError.prototype.errors to inspect output

nodejs/node#43646

* esm: improve performance & tidy tests

nodejs/node#43784

* src: NodeArrayBufferAllocator delegates to v8's allocator

nodejs/node#43594

* chore: update patch indices

* chore: update filenames

* src: refactor IsSupportedAuthenticatedMode

nodejs/node#42368

* src: add --openssl-legacy-provider option

nodejs/node#40478

* lib,src: add source map support for global eval

nodejs/node#43428

* trace_events: trace net connect event

nodejs/node#43903

* deps: update ICU to 71.1

nodejs/node#42655

This fails the test because it's missing https://chromium-review.googlesource.com/c/chromium/deps/icu/+/3841093

* lib: give names to promisified exists() and question()

nodejs/node#43218

* crypto: add CFRG curves to Web Crypto API

nodejs/node#42507

* src: fix memory leak for v8.serialize

nodejs/node#42695

This test does not work for Electron as they do not use V8's
ArrayBufferAllocator.

* buffer: fix atob input validation

nodejs/node#42539

* src: fix ssize_t error from nghttp2.h

nodejs/node#44393

Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com>
Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
esm Issues and PRs related to the ECMAScript Modules implementation. loaders Issues and PRs related to ES module loaders test Issues and PRs related to the tests.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants