Skip to content

Commit

Permalink
reorganize Node.js-specific sources
Browse files Browse the repository at this point in the history
- moved all non-CLI Node.js-specific sources into `lib/nodejs/`
- renamed `WorkerPool` to `BufferedWorkerPool` and udpated filename accordingly.  This is in anticipation of eventually adding a "streaming" worker pool that would communicate via IPC (e.g., `process.send()` and `process.on("message")`); see josdejong/workerpool#51

Signed-off-by: Christopher Hiller <[email protected]>
  • Loading branch information
boneskull committed May 27, 2020
1 parent 769c154 commit 6d7d736
Show file tree
Hide file tree
Showing 17 changed files with 213 additions and 82 deletions.
20 changes: 7 additions & 13 deletions .eslintrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,18 @@ overrides:
env:
node: false
- files:
- 'scripts/**/*.js'
- '.eleventy.js'
- '.wallaby.js'
- 'package-scripts.js'
- 'karma.conf.js'
- '.wallaby.js'
- '.eleventy.js'
- 'bin/*'
- 'docs/_data/**/*.js'
- 'lib/cli/**/*.js'
- 'test/node-unit/**/*.js'
- 'test/integration/options/watch.spec.js'
- 'lib/nodejs/**/*.js'
- 'scripts/**/*.js'
- 'test/integration/helpers.js'
- 'lib/growl.js'
- 'lib/buffered-runner.js'
- 'lib/worker.js'
- 'lib/reporters/buffered.js'
- 'lib/serializer.js'
- 'lib/pool.js'
- 'test/reporters/buffered.spec.js'
- 'docs/_data/**/*.js'
- 'test/integration/options/watch.spec.js'
- 'test/node-unit/**/*.js'
parserOptions:
ecmaVersion: 2018
env:
Expand Down
12 changes: 4 additions & 8 deletions karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,14 @@ module.exports = config => {
browserify: {
debug: true,
configure: function configure(b) {
b.ignore('./lib/cli/*.js')
.ignore('chokidar')
b.ignore('chokidar')
.ignore('fs')
.ignore('glob')
.ignore('./lib/esm-utils.js')
.ignore('path')
.ignore('supports-color')
.ignore('./lib/buffered-runner.js')
.ignore('./lib/reporters/buffered.js')
.ignore('./lib/serializer.js')
.ignore('./lib/worker.js')
.ignore('./lib/pool.js')
.ignore('./lib/esm-utils.js')
.ignore('./lib/cli/*.js')
.ignore('./lib/nodejs/*.js')
.on('bundled', (err, content) => {
if (err) {
throw err;
Expand Down
4 changes: 2 additions & 2 deletions lib/mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
var escapeRe = require('escape-string-regexp');
var path = require('path');
var builtinReporters = require('./reporters');
var growl = require('./growl');
var growl = require('./nodejs/growl');
var utils = require('./utils');
var mocharc = require('./mocharc.json');
var errors = require('./errors');
Expand Down Expand Up @@ -175,7 +175,7 @@ function Mocha(options) {
this.rootHooks(options.rootHooks);
}
if (options.parallel && options.jobs > 1) {
this._runner = require('./buffered-runner');
this._runner = require('./nodejs/buffered-runner');
this.lazyLoadFiles = true;
} else {
this._runner = exports.Runner;
Expand Down
10 changes: 5 additions & 5 deletions lib/pool.js → lib/nodejs/buffered-pool.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const workerpool = require('workerpool');
const {deserialize} = require('./serializer');
const debug = require('debug')('mocha:parallel:pool');
const {cpus} = require('os');
const {createInvalidArgumentTypeError} = require('./errors');
const {createInvalidArgumentTypeError} = require('../errors');

const WORKER_PATH = require.resolve('./worker.js');

Expand Down Expand Up @@ -48,7 +48,7 @@ const WORKER_POOL_DEFAULT_OPTS = {
/**
* A wrapper around a third-party worker pool implementation.
*/
class WorkerPool {
class BufferedWorkerPool {
constructor(opts = WORKER_POOL_DEFAULT_OPTS) {
const maxWorkers = Math.max(1, opts.maxWorkers);

Expand Down Expand Up @@ -102,7 +102,7 @@ class WorkerPool {
'string'
);
}
const serializedOptions = WorkerPool.serializeOptions(options);
const serializedOptions = BufferedWorkerPool.serializeOptions(options);
const result = await this._pool.exec('run', [filepath, serializedOptions]);
return deserialize(result);
}
Expand All @@ -122,7 +122,7 @@ class WorkerPool {
* Instantiates a {@link WorkerPool}.
*/
static create(...args) {
return new WorkerPool(...args);
return new BufferedWorkerPool(...args);
}

/**
Expand Down Expand Up @@ -160,4 +160,4 @@ class WorkerPool {
}
}

exports.WorkerPool = WorkerPool;
exports.BufferedWorkerPool = BufferedWorkerPool;
12 changes: 6 additions & 6 deletions lib/buffered-runner.js → lib/nodejs/buffered-runner.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
'use strict';

const allSettled = require('promise.allsettled');
const Runner = require('./runner');
const Runner = require('../runner');
const {EVENT_RUN_BEGIN, EVENT_RUN_END} = Runner.constants;
const debug = require('debug')('mocha:parallel:buffered-runner');
const {WorkerPool} = require('./pool');
const {BufferedWorkerPool} = require('./buffered-pool');
const {setInterval, clearInterval} = global;
const {createMap} = require('./utils');
const {createMap} = require('../utils');

/**
* Outputs a debug statement with worker stats
* @param {WorkerPool} pool - Worker pool
* @param {BufferedWorkerPool} pool - Worker pool
*/
const debugStats = pool => {
const {totalWorkers, busyWorkers, idleWorkers, pendingTasks} = pool.stats();
Expand Down Expand Up @@ -104,12 +104,12 @@ class BufferedRunner extends Runner {
let debugInterval;

/**
* @type {WorkerPool}
* @type {BufferedWorkerPool}
*/
let pool;

try {
pool = WorkerPool.create({maxWorkers: options.jobs});
pool = BufferedWorkerPool.create({maxWorkers: options.jobs});

sigIntListener = async () => {
if (this._state !== ABORTING) {
Expand Down
2 changes: 1 addition & 1 deletion lib/growl.js → lib/nodejs/growl.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
const os = require('os');
const path = require('path');
const {sync: which} = require('which');
const {EVENT_RUN_END} = require('./runner').constants;
const {EVENT_RUN_END} = require('../runner').constants;

/**
* @summary
Expand Down
128 changes: 128 additions & 0 deletions lib/nodejs/ipc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
'use strict';
/**
* @module IPC
*/
/**
* Module dependencies.
*/

const {
EVENT_SUITE_BEGIN,
EVENT_SUITE_END,
EVENT_TEST_FAIL,
EVENT_TEST_PASS,
EVENT_TEST_PENDING,
EVENT_TEST_BEGIN,
EVENT_TEST_END,
EVENT_TEST_RETRY,
EVENT_DELAY_BEGIN,
EVENT_DELAY_END,
EVENT_HOOK_BEGIN,
EVENT_HOOK_END,
EVENT_RUN_END
} = require('../runner').constants;
const {SerializableEvent, SerializableWorkerResult} = require('../serializer');
const debug = require('debug')('mocha:reporters:ipc');
const Base = require('../reporters/base');

/**
* List of events to listen to; these will be buffered and sent
* when `Mocha#run` is complete (via {@link IPC#done}).
*/
const EVENT_NAMES = [
EVENT_SUITE_BEGIN,
EVENT_SUITE_END,
EVENT_TEST_BEGIN,
EVENT_TEST_PENDING,
EVENT_TEST_FAIL,
EVENT_TEST_PASS,
EVENT_TEST_RETRY,
EVENT_TEST_END,
EVENT_HOOK_BEGIN,
EVENT_HOOK_END
];

/**
* Like {@link EVENT_NAMES}, except we expect these events to only be emitted
* by the `Runner` once.
*/
const ONCE_EVENT_NAMES = [EVENT_DELAY_BEGIN, EVENT_DELAY_END];

/**
* The `IPC` reporter is for use by concurrent runs. Instead of outputting
* to `STDOUT`, etc., it retains a list of events it receives and hands these
* off to the callback passed into {@link Mocha#run}. That callback will then
* return the data to the main process.
*/
class IPC extends Base {
/**
* Listens for {@link Runner} events and retains them in an `events` instance prop.
* @param {Runner} runner
*/
constructor(runner, opts) {
super(runner, opts);

/**
* Retained list of events emitted from the {@link Runner} instance.
* @type {IPCEvent[]}
* @memberOf IPC
*/
const events = (this.events = []);

/**
* mapping of event names to listener functions we've created,
* so we can cleanly _remove_ them from the runner once it's completed.
*/
const listeners = new Map();

/**
* Creates a listener for event `eventName` and adds it to the `listeners`
* map. This is a defensive measure, so that we don't a) leak memory or b)
* remove _other_ listeners that may not be associated with this reporter.
* @param {string} eventName - Event name
*/
const createListener = eventName =>
listeners
.set(eventName, (runnable, err) => {
events.push(SerializableEvent.create(eventName, runnable, err));
})
.get(eventName);

EVENT_NAMES.forEach(evt => {
runner.on(evt, createListener(evt));
});
ONCE_EVENT_NAMES.forEach(evt => {
runner.once(evt, createListener(evt));
});

runner.once(EVENT_RUN_END, () => {
debug('received EVENT_RUN_END');
listeners.forEach((listener, evt) => {
runner.removeListener(evt, listener);
listeners.delete(evt);
});
});
}

/**
* Calls the {@link Mocha#run} callback (`callback`) with the test failure
* count and the array of {@link IPCEvent} objects. Resets the array.
* @param {number} failures - Number of failed tests
* @param {Function} callback - The callback passed to {@link Mocha#run}.
*/
done(failures, callback) {
callback(SerializableWorkerResult.create(this.events, failures));
this.events = []; // defensive
}
}

/**
* Serializable event data from a `Runner`. Keys of the `data` property
* beginning with `__` will be converted into a function which returns the value
* upon deserialization.
* @typedef {Object} IPCEvent
* @property {string} name - Event name
* @property {object} data - Event parameters
*/

module.exports = IPC;
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ const {
EVENT_HOOK_BEGIN,
EVENT_HOOK_END,
EVENT_RUN_END
} = require('../runner').constants;
} = require('../../runner').constants;
const {SerializableEvent, SerializableWorkerResult} = require('../serializer');
const debug = require('debug')('mocha:reporters:buffered');
const Base = require('./base');
const Base = require('../../reporters/base');

/**
* List of events to listen to; these will be buffered and sent
Expand Down
4 changes: 2 additions & 2 deletions lib/serializer.js → lib/nodejs/serializer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';

const {type} = require('./utils');
const {createInvalidArgumentTypeError} = require('./errors');
const {type} = require('../utils');
const {createInvalidArgumentTypeError} = require('../errors');
const debug = require('debug')('mocha:serializer');

const SERIALIZABLE_RESULT_NAME = 'SerializableWorkerResult';
Expand Down
6 changes: 3 additions & 3 deletions lib/worker.js → lib/nodejs/worker.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
const {
createInvalidArgumentTypeError,
createInvalidArgumentValueError
} = require('./errors');
} = require('../errors');
const workerpool = require('workerpool');
const Mocha = require('./mocha');
const Mocha = require('../mocha');
const {
handleRequires,
validatePlugin,
loadRootHooks
} = require('./cli/run-helpers');
} = require('../cli/run-helpers');
const d = require('debug');
const debug = d.debug(`mocha:parallel:worker:${process.pid}`);
const isDebugEnabled = d.enabled(`mocha:parallel:worker:${process.pid}`);
Expand Down
2 changes: 1 addition & 1 deletion package-scripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function test(testName, mochaParams) {
module.exports = {
scripts: {
build: {
script: `browserify -e browser-entry.js --plugin ./scripts/dedefine --ignore './lib/cli/*.js' --ignore "./lib/esm-utils.js" --ignore 'chokidar' --ignore 'fs' --ignore 'glob' --ignore 'path' --ignore 'supports-color' --ignore './lib/buffered-runner.js' --ignore './lib/serializer.js' --ignore './lib/reporters/buffered.js' --ignore './lib/worker.js' --ignore './lib/pool.js' -o mocha.js`,
script: `browserify -e browser-entry.js --plugin ./scripts/dedefine --ignore './lib/cli/*.js' --ignore "./lib/esm-utils.js" --ignore 'chokidar' --ignore 'fs' --ignore 'glob' --ignore 'path' --ignore 'supports-color' --ignore './lib/nodejs/*.js' -o mocha.js`,
description: 'Build browser bundle'
},
lint: {
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,11 @@
"glob": false,
"path": false,
"supports-color": false,
"./lib/serializer.js": false,
"./lib/reporters/buffered.js": false,
"./lib/buffered-reporter.js": false,
"./lib/worker.js": false,
"./lib/pool.js": false
"./lib/nodejs/serializer.js": false,
"./lib/nodejs/reporters/buffered.js": false,
"./lib/nodejs/buffered-reporter.js": false,
"./lib/nodejs/worker.js": false,
"./lib/nodejs/buffered-pool.js": false
},
"prettier": {
"singleQuote": true,
Expand Down
Loading

0 comments on commit 6d7d736

Please sign in to comment.