Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .mocharc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright IBM Corp. 2020. All Rights Reserved.
// Node module: loopback-next
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

// Reuse the mocha config from `@loopback/cli`
const config = require('./packages/cli/.mocharc.js');

// Set max listeners to 16 for testing to avoid the following warning:
// (node:11220) MaxListenersExceededWarning: Possible EventEmitter
// 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
Copy link
Member

Choose a reason for hiding this comment

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

I think it's a problem in our test suite when we start apps but don't stop them. Instead of suppressing the helpful warning, can we please fix our tests to always stop the applications started?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I cannot find any more places that stop is not called with start.

Copy link
Member

Choose a reason for hiding this comment

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

I am running Node.js 14.4.0 and haven't encountered MaxListenersExceededWarning. Could you please double check that this is still a problem? Is it perhaps specific to older versions of Node or a timing conditions on CI build servers?

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.


module.exports = config;
2 changes: 2 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"program": "${workspaceRoot}/packages/build/node_modules/mocha/bin/_mocha",
"runtimeArgs": ["-r", "${workspaceRoot}/packages/build/node_modules/source-map-support/register"],
"cwd": "${workspaceRoot}",
"autoAttachChildProcesses": true,
"args": [
"--config",
"${workspaceRoot}/packages/build/config/.mocharc.json",
Expand All @@ -26,6 +27,7 @@
"program": "${workspaceRoot}/bin/mocha-current-file",
"runtimeArgs": ["-r", "${workspaceRoot}/packages/build/node_modules/source-map-support/register"],
"cwd": "${workspaceRoot}",
"autoAttachChildProcesses": true,
"args": [
"--config",
"${workspaceRoot}/packages/build/config/.mocharc.json",
Expand Down
15 changes: 14 additions & 1 deletion packages/build/bin/run-mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Usage:

'use strict';

const path = require('path');
const fs = require('fs-extra');

function run(argv, options) {
const utils = require('./utils');

Expand All @@ -24,7 +27,6 @@ function run(argv, options) {
!utils.isOptionSet(
mochaOpts,
'--config', // mocha 6.x
'--opts', // legacy
'--package', // mocha 6.x
'--no-config', // mocha 6.x
) && !utils.mochaConfiguredForProject();
Expand Down Expand Up @@ -59,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.

if (!mochaOpts.includes('--parallel')) {
const pkgFile = path.join(utils.getPackageDir(), 'package.json');
if (fs.existsSync(pkgFile)) {
const pkg = fs.readJsonSync(pkgFile);
if (pkg.name.startsWith('@loopback/')) {
mochaOpts.push('--parallel');
}
}
}

const args = [...mochaOpts];

return utils.runCLI('mocha/bin/mocha', args, options);
Expand Down
1 change: 0 additions & 1 deletion packages/build/bin/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,6 @@ function mochaConfiguredForProject() {
'.mocharc.json',
'.mocharc.yaml',
'.mocharc.yml',
'test/mocha.opts',
];
return configFiles.some(f => {
const configFile = path.join(getPackageDir(), f);
Expand Down
2 changes: 1 addition & 1 deletion packages/build/config/.mocharc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"require": "source-map-support/register",
"require": ["source-map-support/register"],
"recursive": true,
"exit": true,
"reporter": "dot"
Expand Down
104 changes: 6 additions & 98 deletions packages/build/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 53 additions & 0 deletions packages/cli/.mocharc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright IBM Corp. 2020. All Rights Reserved.
// Node module: @loopback/cli
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT

// A workaround to use `--require ./test/snapshot-matcher.js` so that root
// hooks are executed by mocha parallel testing for each job

const debug = require('debug')('loopback:cli:test');

/**
* Build mocha config for `@loopback/cli`
*/
function buildConfig() {
// Use the default config from `@loopback/build`
const mochaConfig = require('@loopback/build/config/.mocharc.json');
debug('Default mocha config:', mochaConfig);
// 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.


// 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

if (jobs === 0) {
// Disable parallel testing
config.parallel = false;
} else if (jobs > 0) {
// Override the default number of concurrent jobs
config.parallel = true;
config.jobs = jobs;
}
addRequire(config, mochaHooksFile);
debug('Final mocha config:', config);
return config;
}

/**
* Add a new entry to the mocha config.require
* @param {object} config - Mocha config
* @param {string} mochaHooksFile - A module to be loaded by mocha
*/
function addRequire(config, mochaHooksFile) {
if (typeof config.require === 'string') {
config.require = [config.require, mochaHooksFile];
} else if (Array.isArray(config.require)) {
config.require = config.require.concat(mochaHooksFile);
} else {
config.require = mochaHooksFile;
}
}

module.exports = buildConfig();
Loading