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

test: add a test to make sure the modules can be required independently #24402

Closed
wants to merge 3 commits into from

Conversation

joyeecheung
Copy link
Member

@joyeecheung joyeecheung commented Nov 16, 2018

The first patch comes from #24396

So, I am not entirely sure if it's worth adding a test that launches ~75 child processes just to make sure we have a cleaner dependency graph in the internal modules..so just open this to see what others think.

test: add a test to make sure the modules can be required

This patch adds a test that makes sure all the modules (internal
or not) can be independently required - that is, when there is
circular dependency, one module does not rely on another module
being loaded first to initialize, instead it should lazily load
that dependency after initialization.

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines

The default encoding can be retrieved via
`require('internal/crypto/util').getDefaultEncoding` instead of
the deprecated crypto.DEFAULT_ENCODING which triggers a warning.

Background:

The require chain goes like this:

```
internal/streams/lazy_transform.js
  -> crypto.js
  -> internal/crypto/cipher.js (uses LazyTransform in the global scope)
  -> internal/streams/lazy_transform.js
```

So when `internal/streams/lazy_transform.js` is required before
`lib/crypto.js`, we have a circular dependency and since
`internal/crypto/cipher.js` uses destructuring to use LazyTransform
we will get an error. And it can also trigger a warning if
lazy_transform.js is the first file that touches
crypto.DEFAULT_ENCODING.
This patch adds a test that makes sure all the modules (internal
or not) can be independently required - that is, when there is
circular dependency, one module does not rely on another module
being loaded first to initialize, instead it should lazily load
that dependency after initialization.
Copy link
Member

@bnoordhuis bnoordhuis left a comment

Choose a reason for hiding this comment

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

Test seems fine to me.

@addaleax
Copy link
Member

Looks like the linter failures are related?

@joyeecheung
Copy link
Member Author

@addaleax Yes, I didn't run the linters before submitting this, my bad, will fix later

@joyeecheung
Copy link
Member Author

@refack
Copy link
Contributor

refack commented Nov 23, 2018

AIX is strange ¯\(ツ)

test.sequential/test-native-module-deps

/home/iojs/build/workspace/node-test-commit-aix/nodes/aix61-ppc64/test/sequential/test-native-module-deps.js:30
  child.stdout.on('data', (data) => (stdout += data.toString()));
               ^

TypeError: Cannot read property 'on' of undefined
    at run (/home/iojs/build/workspace/node-test-commit-aix/nodes/aix61-ppc64/test/sequential/test-native-module-deps.js:30:16)
    at Object.<anonymous> (/home/iojs/build/workspace/node-test-commit-aix/nodes/aix61-ppc64/test/sequential/test-native-module-deps.js:19:3)
    at Module._compile (internal/modules/cjs/loader.js:722:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:733:10)
    at Module.load (internal/modules/cjs/loader.js:620:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
    at Function.Module._load (internal/modules/cjs/loader.js:552:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:775:12)
    at startup (internal/bootstrap/node.js:300:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:826:3)

@refack
Copy link
Contributor

refack commented Nov 23, 2018

So on a slow platform like debian8-docker-armv7, this test takes 19s
https://ci.nodejs.org/job/node-test-commit-arm/20217/nodes=debian8-docker-armv7/testReport/(root)/test/sequential_test_native_module_deps/

I think it's a good test to have, but maybe move it to one of the suites that run only one a day (ATM it's internet and benchmark)

/CC @nodejs/testing

@refack refack added module Issues and PRs related to the module subsystem. test Issues and PRs related to the tests. cli Issues and PRs related to the Node.js command line interface. labels Nov 23, 2018
let stderr = '';
child.stdout.on('data', (data) => (stdout += data.toString()));
child.stderr.on('data', (data) => (stderr += data.toString()));
child.on('close', (code) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

add common.mustCall

Copy link
Contributor

@refack refack left a comment

Choose a reason for hiding this comment

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

Some suggestions

console.log(stderr);
console.log('----- stdout ----');
console.log(stdout);
assert.strictEqual(code, 0);
Copy link
Contributor

@refack refack Nov 23, 2018

Choose a reason for hiding this comment

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

IIUC this doesn't match L33
Ahh you want this to fail, so assert.fail(`exit code: ${code}`).

Another thought, this will lead to the test failing for the first bad module masking, any other possible fails. Maybe replace with

    common.mustCall(() => `exit code: ${code} for module: ${key}`);

The returned function will never get called, but will make the test fail when the process exits.

Copy link
Member Author

Choose a reason for hiding this comment

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

@refack In general I think it's fine to just fail when we encounter the first module without a clean dependency graph, and fix them one by one?

}

function run(key) {
const child = fork(__filename,
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe use:

Suggested change
const child = fork(__filename,
const child = execFile(process.execPath, ['-e', `require('${key}')])`

this way you don't need the self-reference, and eliminate L6-L9

Copy link
Member Author

@joyeecheung joyeecheung Nov 23, 2018

Choose a reason for hiding this comment

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

@refack -e introduces noise in the dependency graph because that option also leads to additional module loads. Same goes to -p. It somewhat weakens the test.

Copy link
Contributor

Choose a reason for hiding this comment

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

Then maybe use a fixture?
It seems to me like in this case the self referenced part makes the file look awkward. And the usual benefit of having all the test code in one place, is not that beneficial since the child code is just one expression.
But it's just a style nit, and I defer to your decision.

Copy link
Contributor

Choose a reason for hiding this comment

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

New idea, a variation on (either with shell or by using child.stdin):

const child = exec(`echo "require('${key}')" | `${process.execPath}` --`, {shell: true});

@joyeecheung
Copy link
Member Author

joyeecheung commented Nov 23, 2018

I think it's a good test to have, but maybe move it to one of the suites that run only one a day (ATM it's internet and benchmark)

I thought about that, but this test looks weird in either of those places...maybe we can create a new folder for slower tests and just move them all there? Maybe also some of the slow but less critical tests identified in #23251

@refack
Copy link
Contributor

refack commented Nov 23, 2018

maybe we can create a new folder for slower tests and just move them all there? Maybe also some of the slow but less critical tests identified in #23251

I'll put it in my list of goals

@BridgeAR
Copy link
Member

I like the test. It is pretty heavy thought.

@Trott do we have more tests that only run once a day?

@BridgeAR BridgeAR force-pushed the master branch 2 times, most recently from 8ae28ff to 2935f72 Compare May 31, 2020 12:19
@jasnell jasnell added the stalled Issues and PRs that are stalled. label Jul 7, 2020
@github-actions
Copy link
Contributor

github-actions bot commented Nov 6, 2020

Closing this because it has stalled. Feel free to reopen if this PR is still relevant, or to ping the collaborator who labelled it stalled if you have any questions.

@github-actions github-actions bot closed this Nov 6, 2020
@Trott
Copy link
Member

Trott commented Nov 9, 2020

I like the test. It is pretty heavy thought.

@Trott do we have more tests that only run once a day?

Sorry for the late reply, but pummel tests run once a day.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cli Issues and PRs related to the Node.js command line interface. module Issues and PRs related to the module subsystem. stalled Issues and PRs that are stalled. test Issues and PRs related to the tests.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants