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

feat: enable parallel mocha testing #5011

Closed
wants to merge 3 commits into from
Closed

Conversation

raymondfeng
Copy link
Contributor

@raymondfeng raymondfeng commented Apr 2, 2020

Enable parallel mocha testing - see #3159 (comment)

I'm starting to break down this PR into a few smaller ones:

Checklist

👉 Read and sign the CLA (Contributor License Agreement) 👈

  • npm test passes on your machine
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • API Documentation in code was updated
  • Documentation in /docs/site was updated
  • Affected artifact templates in packages/cli were updated
  • Affected example projects in examples/* were updated

👉 Check out how to submit a PR 👈

@raymondfeng
Copy link
Contributor Author

The snapshot-related cli tests are still failing. I think I have a theory as follows:

  1. The snapshots.js creates a global beforeEach hook (which is done once per process with node.js module require)
  2. Parallel mocha uses a pool of worker processes
  3. When the worker process tests the 1st file, beforeEach is correctly called
  4. When the worker process is reused to test a 2nd file, beforeEach is not available to mocha as the node require cache is not flushed. As a result, beforeEach is not invoked to refresh currentTest
  5. As a result, the last currentTest from the 1st test file is accidentally used for other tests and it fails

@raymondfeng
Copy link
Contributor Author

@boneskull Is it possible to have something as follows to be picked up by mocha without ---require or --file?

'use strict';
exports.mochaHooks = {
  beforeAll() {
    console.log('beforeAll');
  },
  beforeEach() {
    console.log('beforeEach');
  },
  afterAll() {
    console.log('afterAll');
  },
  afterEach() {
    console.log('afterEach');
  }
};

@raymondfeng raymondfeng force-pushed the test-parallel-mocha branch 12 times, most recently from dcb0093 to 377a949 Compare April 10, 2020 05:56
@raymondfeng raymondfeng changed the title [RFC] Enable parallel mocha testing feat: enable parallel mocha testing Jun 10, 2020
@raymondfeng raymondfeng marked this pull request as ready for review June 10, 2020 23:37
Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

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

I am not happy with using root-level hooks for snapshot setup and want to investigate different approaches to see if I can find a more elegant solution. I am planning to work on this tomorrow (Friday), please give me few more days before continuing with the solution proposed here.

@bajtos
Copy link
Member

bajtos commented Jun 11, 2020

Let's not mix the upgrade to Mocha v8.x with the transition to parallel tests please. I'd like to see a standalone PR to upgrade to Mocha 8.x and make the necessary updates in our config files. I think commits like cbba724 and f9af11e can be landed independently too.

Mocha 8.x dropped support for mocha.opts file, which we still support in run-mocha script. This should be fixed as part of the upgrade to Mocha 8.x.

@boneskull
Copy link
Contributor

agree that parallel mode shouldn’t be the default for users.

BREAKING CHANGE: We have upgraded to `mocha@8.0.1` and removed support for
`--opts` and `test/mocha.opts`. It may break your application if it depends
on earlier version of `@loopback/build` for `npm test`.

See a list of breaking changes of mocha 8.x at:
https://github.com/mochajs/mocha/releases/tag/v8.0.0
…sting

- try with require to register root hooks
- add .mocharc.js for packages/cli to register root hooks
- add the option to use env var MOCHA_JOBS to override parallel testing parameters
@bajtos
Copy link
Member

bajtos commented Jun 12, 2020

@raymondfeng can you please extract 7334f20 in to a standalone pull request to get it landed sooner, and make it easier for others (me in particular) to experiment with different approaches to parallel testing?

// memory leak detected. 11 SIGTERM listeners added to [process].
// Use emitter.setMaxListeners() to increase limit
// It only happens when multiple app instances are started but not stopped
process.setMaxListeners(16);
Copy link
Member

@bajtos bajtos Jun 12, 2020

Choose a reason for hiding this comment

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

How is the change in setMaxListeners(16) relevant to snapshot matching? I think this belongs to a different commit.

// Resolve `./test/snapshot-matcher.js` to get the absolute path
const mochaHooksFile = require.resolve('./test/snapshot-matcher.js');
debug('Root hooks for --require %s', mochaHooksFile);
const config = {...mochaConfig, timeout: 5000};
Copy link
Member

Choose a reason for hiding this comment

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

I find this approach brittle because it requires us to deal with root hooks both inside the package test setup and in monorepo test setup.

Copy link
Member

Choose a reason for hiding this comment

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

In #5724, I have proposed a fix that does not leak the knowledge about snapshot hooks outside of CLI tests.

@@ -58,6 +61,17 @@ function run(argv, options) {
mochaOpts.splice(lang, 2);
}

// Set `--parallel` for `@loopback/*` packages
Copy link
Member

@bajtos bajtos Jun 12, 2020

Choose a reason for hiding this comment

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

I am not sure if this is a good idea, because it affects code outside our monorepo too. Two examples:

  • Example projects created via lb4 example <name>. Besides the extra complexity related to parallel testing, I am concerned about the impact on performance. Based on my measurement, examples/todo tests are ~15x slower when executed in parallel:

    examples/todo$ npm t
    (...)
      29 passing (481ms)
    
    examples/todo$ npm t -- --parallel
    (...)
      29 passing (7s)
    
  • External repositories like https://github.com/strongloop/loopback4-example-shopping. I am not sure how much work is required to support parallel testing in the shopping example and I would rather not block upgrading to the latest @loopback/build version until we can figure out parallel testing.

I am proposing to enable parallel testing by changing npm run mocha script to add --parallel flag to mocha CLI options.

Copy link
Member

@bajtos bajtos Jun 12, 2020

Choose a reason for hiding this comment

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

See e.g. b44c7ee

-"mocha": "node packages/build/bin/run-mocha --lang en_US.UTF-8 --timeout 5000 \"packages/*/dist/__tests__/**/*.js\" \"extensions/*/dist/__tests__/**/*.js\" \"examples/*/dist/__tests__/**/*.js\" \"packages/cli/test/**/*.js\" \"packages/build/test/*/*.js\"",
+"mocha": "node packages/build/bin/run-mocha --lang en_US.UTF-8 --timeout 15000 --parallel \"packages/*/dist/__tests__/**/*.js\" \"extensions/*/dist/__tests__/**/*.js\" \"examples/*/dist/__tests__/**/*.js\" \"packages/cli/test/**/*.js\" \"packages/build/test/*/*.js\"",

Having said that, I think it's time to move flags from run-mocha CLI args into the monorepo-level .mocharc.js file. That way they are always applied, for example when running a subset of tests manually via node packages/build/bin/run-mocha path/to/some/files.

@bajtos
Copy link
Member

bajtos commented Jun 23, 2020

Opened #5813 to rework the snapshot matcher to use Mocha global hooks, without actually enabling the parallel mode yet.

const config = {...mochaConfig, timeout: 5000};

// Allow env var `MOCHA_JOBS` to override parallel testing parameters
const jobs = +process.env.MOCHA_JOBS;
Copy link
Member

Choose a reason for hiding this comment

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

I feel we don't need to support process.env.MOCHA_JOBS as it's already possible to change the number of jobs (worker processes) by using -j command line argument and disable parallel execution by setting the number of jobs to 1.

$ npm run mocha -- -j 1

@bajtos
Copy link
Member

bajtos commented Jun 26, 2020

I am proposing to close this pull request in favor of #5831.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
developer-experience Issues affecting ease of use and overall experience of LB users
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants