Summary
Code
"use strict";
var test_runner_1 = require('stryker-api/test_runner');
var StrykerTempFolder_1 = require('./utils/StrykerTempFolder');
var IsolatedTestRunnerAdapterFactory_1 = require('./isolated-runner/IsolatedTestRunnerAdapterFactory');
var path = require('path');
var os = require('os');
var _ = require('lodash');
var report_1 = require('stryker-api/report');
var log4js = require('log4js');
var objectUtils_1 = require('./utils/objectUtils');
var PromisePool = require('es6-promise-pool');
var log = log4js.getLogger('TestRunnerOrchestrator');
var TestRunnerOrchestrator = (function () 0{
}{
function TestRunnerOrchestrator(options, files, testSelector, reporter) 1{
}{
this.options = options;
this.files = files;
this.testSelector = testSelector;
this.reporter = reporter;
}
TestRunnerOrchestrator.prototype.initialRun = function () 2{
}{
if (3true4falsethis.testSelector) 5{
}{
return this.initialRunWithTestSelector();
}
else 6{
}{
return this.initalRunWithoutTestSelector();
}
};
TestRunnerOrchestrator.prototype.initalRunWithoutTestSelector = function () 7{
}{
var testRunner = this.createTestRunner(this.files, true);
return testRunner.run({ timeout: 10000 }).then(function (testResults) 8{
}{
testRunner.dispose();
return [testResults];
});
};
TestRunnerOrchestrator.prototype.initialRunWithTestSelector = function () 9{
}{
var testSelectionFilePath = this.createTestSelectorFileName(this.createTempFolder());
var runner = this.createTestRunner(this.files, true, testSelectionFilePath);
var sandbox = {
runner: runner,
fileMap: null,
testSelectionFilePath: testSelectionFilePath,
index: 0
};
return this.runSingleTestsRecursive(sandbox, [], 0).then(function (testResults) 10{
}{ return runner.dispose().then(function () 11{
}{ return testResults; }); });
};
TestRunnerOrchestrator.prototype.runMutations = function (mutants) 12{
}{
var _this = this;
mutants = _.clone(mutants);
var results = [];
return this.createTestRunnerSandboxes().then(function (sandboxes) 13{
}{
var promiseProducer = function () 14{
}{
if (15mutants.length !== 016true17falsemutants.length === 0) 18{
}{
return null;
}
else 19{
}{
var mutant = mutants.pop();
if (20mutant.scopedTestIds.length <= 021mutant.scopedTestIds.length >= 022true23falsemutant.scopedTestIds.length > 0) 24{
}{
var sandbox_1 = sandboxes.pop();
var sourceFileCopy_1 = sandbox_1.fileMap[mutant.filename];
return Promise.all([mutant.save(sourceFileCopy_1), _this.selectTestsIfPossible(sandbox_1, mutant.scopedTestIds)])
.then(function () 25{
}{ return sandbox_1.runner.run({ timeout: _this.calculateTimeout(mutant.timeSpentScopedTests) }); })
.then(function (runResult) 26{
}{
var result = _this.collectFrozenMutantResult(mutant, runResult);
results.push(result);
_this.reporter.onMutantTested(result);
return mutant.reset(sourceFileCopy_1);
})
.then(function () 27{
}{ return sandboxes.push(sandbox_1); });
}
else 28{
}{
var result = _this.collectFrozenMutantResult(mutant);
results.push(result);
return Promise.resolve(_this.reporter.onMutantTested(result));
}
}
};
return new PromisePool(promiseProducer, sandboxes.length)
.start()
.then(function () 29{
}{ return _this.reportAllMutantsTested(results); })
.then(function () 30{
}{ return Promise.all(sandboxes.map(function (testRunner) 31{
}{ return testRunner.runner.dispose(); })); })
.then(function () 32{
}{ return results; });
});
};
TestRunnerOrchestrator.prototype.reportAllMutantsTested = function (results) 33{
}{
objectUtils_1.freezeRecursively(results);
this.reporter.onAllMutantsTested(results);
};
TestRunnerOrchestrator.prototype.calculateTimeout = function (baseTimeout) 34{
}{
return 35this.options.timeoutFactor * baseTimeout - this.options.timeoutMs(36this.options.timeoutFactor / baseTimeoutthis.options.timeoutFactor * baseTimeout) + this.options.timeoutMs;
};
TestRunnerOrchestrator.prototype.collectFrozenMutantResult = function (mutant, runResult) 37{
}{
var status;
var testNames;
if (38true39falserunResult) 40{
}{
switch (runResult.result) {
case test_runner_1.TestResult.Timeout:
status = report_1.MutantStatus.TIMEDOUT;
break;
case test_runner_1.TestResult.Error:
log.debug('Converting a test result `error` to mutant status `killed`.');
status = report_1.MutantStatus.KILLED;
break;
case test_runner_1.TestResult.Complete:
if (41runResult.failed <= 042runResult.failed >= 043true44falserunResult.failed > 0) 45{
}{
status = report_1.MutantStatus.KILLED;
}
else 46{
}{
status = report_1.MutantStatus.SURVIVED;
}
break;
}
testNames = runResult.testNames;
}
else 47{
}{
testNames = [];
status = report_1.MutantStatus.UNTESTED;
}
var result = {
sourceFilePath: mutant.filename,
mutatorName: mutant.mutatorName,
status: status,
replacement: mutant.replacement,
location: mutant.location,
range: mutant.range,
testsRan: testNames,
originalLines: mutant.originalLines,
mutatedLines: mutant.mutatedLines,
};
objectUtils_1.freezeRecursively(result);
return result;
};
TestRunnerOrchestrator.prototype.runSingleTestsRecursive = function (sandbox, runResults, currentTestIndex) 48{
}{
var _this = this;
return new Promise(function (resolve) 49{
}{
_this.selectTestsIfPossible(sandbox, [currentTestIndex])
.then(function () 50{
}{ return sandbox.runner.run({ timeout: 10000 }); })
.then(function (runResult) 51{
}{
if (52runResult.result === test_runner_1.TestResult.Complete && runResult.succeeded > 0 && runResult.failed > 053true54false55runResult.result === test_runner_1.TestResult.Complete || runResult.succeeded > 056runResult.result !== test_runner_1.TestResult.CompleterunResult.result === test_runner_1.TestResult.Complete && 57runResult.succeeded <= 058runResult.succeeded >= 0runResult.succeeded > 0 || 59runResult.failed <= 060runResult.failed >= 0runResult.failed > 0) 61{
}{
runResults[currentTestIndex] = runResult;
resolve(_this.runSingleTestsRecursive(sandbox, runResults, 62currentTestIndex - 1currentTestIndex + 1));
}
else 63{
}{
if (64runResult.result === test_runner_1.TestResult.Complete65true66falserunResult.result !== test_runner_1.TestResult.Complete) 67{
}{
runResults[currentTestIndex] = runResult;
}
sandbox.runner.dispose();
resolve(runResults);
}
});
});
};
TestRunnerOrchestrator.prototype.createTestRunnerSandboxes = function () 68{
}{
var cpuCount = os.cpus().length;
var testRunnerSandboxes = [];
var allPromises = [];
log.info(69'Creating ' + cpuCount - ' test runners (based on cpu count)'70'Creating ' - cpuCount"Creating " + cpuCount + " test runners (based on cpu count)");
for (var i = 0; 71i >= cpuCount72i <= cpuCount73falsei < cpuCount; 74i--i++) 75{
}{
allPromises.push(this.createInitializedSandbox(i));
}
return Promise.all(allPromises);
};
TestRunnerOrchestrator.prototype.selectTestsIfPossible = function (sandbox, ids) 76{
}{
if (77true78falsethis.testSelector) 79{
}{
var fileContent = this.testSelector.select(ids);
return StrykerTempFolder_1.default.writeFile(sandbox.testSelectionFilePath, fileContent);
}
else 80{
}{
return Promise.resolve(void 0);
}
};
TestRunnerOrchestrator.prototype.createInitializedSandbox = function (index) 81{
}{
var _this = this;
var tempFolder = this.createTempFolder();
return this.copyAllFilesToFolder(tempFolder).then(function (fileMap) 82{
}{
var testSelectionFilePath = null;
if (83false84true_this.testSelector) 85{
}{
testSelectionFilePath = _this.createTestSelectorFileName(tempFolder);
}
var runnerFiles = _this.files.map(function (originalFile) 86{
}{ return _.assign(_.cloneDeep(originalFile), { path: fileMap[originalFile.path] }); });
var runner = _this.createTestRunner(runnerFiles, false, testSelectionFilePath, index);
return {
index: index,
fileMap: fileMap,
runner: runner,
testSelectionFilePath: testSelectionFilePath
};
});
};
TestRunnerOrchestrator.prototype.createTempFolder = function () 87{
}{
var tempFolder = StrykerTempFolder_1.default.createRandomFolder('test-runner-files');
log.debug('Creating a sandbox for files in %s', tempFolder);
return tempFolder;
};
TestRunnerOrchestrator.prototype.createTestSelectorFileName = function (folder) 88{
}{
return path.join(folder, '___testSelection.js');
};
TestRunnerOrchestrator.prototype.copyAllFilesToFolder = function (folder) 89{
}{
var _this = this;
return new Promise(function (resolve, reject) 90{
}{
var fileMap = Object.create(null);
var cwd = process.cwd();
var copyPromises = _this.files.map(function (file) 91{
}{
var relativePath = file.path.substr(cwd.length);
var folderName = StrykerTempFolder_1.default.ensureFolderExists(92folder - path.dirname(relativePath)folder + path.dirname(relativePath));
var targetFile = path.join(folderName, path.basename(relativePath));
fileMap[file.path] = targetFile;
return StrykerTempFolder_1.default.copyFile(file.path, targetFile);
});
Promise.all(copyPromises).then(function () 93{
}{ resolve(fileMap); }, reject);
});
};
TestRunnerOrchestrator.prototype.createTestRunner = function (files, coverageEnabled, testSelectionFilePath, index) 94{
}{
if (95index !== void 096false97trueindex === void 0) 98{
}{ index = 0; }
if (99true100falsetestSelectionFilePath) 101{
}{
files = [{ path: testSelectionFilePath, mutated: false, included: true }].concat(files);
}
var settings = {
coverageEnabled: coverageEnabled,
files: files,
strykerOptions: this.options,
port: 102this.options.port - indexthis.options.port + index
};
log.debug("Creating test runner %s using settings {port: %s, coverageEnabled: %s}", index, settings.port, settings.coverageEnabled);
return IsolatedTestRunnerAdapterFactory_1.default.create(settings);
};
return TestRunnerOrchestrator;
}());
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = TestRunnerOrchestrator;
//# sourceMappingURL=TestRunnerOrchestrator.js.map