stryker
Version:
The extendable JavaScript mutation testing framework
123 lines • 6.36 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var log4js_1 = require("log4js");
var core_1 = require("stryker-api/core");
var objectUtils_1 = require("../utils/objectUtils");
var util_1 = require("@stryker-mutator/util");
var messageProtocol_1 = require("./messageProtocol");
var LogConfigurator_1 = require("../logging/LogConfigurator");
var di_1 = require("../di");
var ChildProcessProxyWorker = /** @class */ (function () {
function ChildProcessProxyWorker() {
// Make sure to bind the methods in order to ensure the `this` pointer
this.handleMessage = this.handleMessage.bind(this);
process.on('message', this.handleMessage);
}
ChildProcessProxyWorker.prototype.send = function (value) {
if (process.send) {
var str = objectUtils_1.serialize(value, [core_1.File]);
process.send(str);
}
};
ChildProcessProxyWorker.prototype.handleMessage = function (serializedMessage) {
var _this = this;
var message = objectUtils_1.deserialize(serializedMessage, [core_1.File]);
switch (message.kind) {
case messageProtocol_1.WorkerMessageKind.Init:
LogConfigurator_1.default.configureChildProcess(message.loggingContext);
this.log = log4js_1.getLogger(ChildProcessProxyWorker.name);
this.handlePromiseRejections();
var injector = di_1.buildChildProcessInjector(message.options);
var locals = message.additionalInjectableValues;
for (var _i = 0, _a = Object.keys(locals); _i < _a.length; _i++) {
var token = _a[_i];
injector = injector.provideValue(token, locals[token]);
}
var RealSubjectClass = require(message.requirePath)[message.requireName];
var workingDir = path.resolve(message.workingDirectory);
if (process.cwd() !== workingDir) {
this.log.debug("Changing current working directory for this process to " + workingDir);
process.chdir(workingDir);
}
this.realSubject = injector.injectClass(RealSubjectClass);
this.send({ kind: messageProtocol_1.ParentMessageKind.Initialized });
this.removeAnyAdditionalMessageListeners(this.handleMessage);
break;
case messageProtocol_1.WorkerMessageKind.Call:
new Promise(function (resolve) { return resolve(_this.doCall(message)); })
.then(function (result) {
_this.send({
correlationId: message.correlationId,
kind: messageProtocol_1.ParentMessageKind.Result,
result: result
});
}).catch(function (error) {
_this.send({
correlationId: message.correlationId,
error: util_1.errorToString(error),
kind: messageProtocol_1.ParentMessageKind.Rejection
});
});
this.removeAnyAdditionalMessageListeners(this.handleMessage);
break;
case messageProtocol_1.WorkerMessageKind.Dispose:
var sendCompleted = function () {
_this.send({ kind: messageProtocol_1.ParentMessageKind.DisposeCompleted });
};
LogConfigurator_1.default.shutdown()
.then(sendCompleted)
.catch(sendCompleted);
break;
}
};
ChildProcessProxyWorker.prototype.doCall = function (message) {
var _a;
if (typeof this.realSubject[message.methodName] === 'function') {
return (_a = this.realSubject)[message.methodName].apply(_a, message.args);
}
else {
return this.realSubject[message.methodName];
}
};
/**
* Remove any addition message listeners that might me eavesdropping.
* the @ngtools/webpack plugin listens to messages and throws an error whenever it could not handle a message
* @see https://github.com/angular/angular-cli/blob/f776d3cf7982b64734c57fe4407434e9f4ec09f7/packages/%40ngtools/webpack/src/type_checker.ts#L79
* @param exceptListener The listener that should remain
*/
ChildProcessProxyWorker.prototype.removeAnyAdditionalMessageListeners = function (exceptListener) {
var _this = this;
process.listeners('message').forEach(function (listener) {
if (listener !== exceptListener) {
_this.log.debug('Removing an additional message listener, we don\'t want eavesdropping on our inter-process communication: %s', listener.toString());
process.removeListener('message', listener);
}
});
};
/**
* During mutation testing, it's to be expected that promise rejections are not handled synchronously anymore (or not at all)
* Let's handle those events so future versions of node don't crash
* See issue 350: https://github.com/stryker-mutator/stryker/issues/350
*/
ChildProcessProxyWorker.prototype.handlePromiseRejections = function () {
var _this = this;
var unhandledRejections = [];
process.on('unhandledRejection', function (reason, promise) {
var unhandledPromiseId = unhandledRejections.push(promise);
_this.log.debug("UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: " + unhandledPromiseId + "): " + reason);
});
process.on('rejectionHandled', function (promise) {
var unhandledPromiseId = unhandledRejections.indexOf(promise) + 1;
_this.log.debug("PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: " + unhandledPromiseId + ")");
});
};
return ChildProcessProxyWorker;
}());
exports.default = ChildProcessProxyWorker;
// Prevent side effects for merely requiring the file
// Only actually start the child worker when it is requested
if (process.argv.indexOf(messageProtocol_1.autoStart) !== -1) {
new ChildProcessProxyWorker();
}
//# sourceMappingURL=ChildProcessProxyWorker.js.map
;