UNPKG

3.97 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.SandboxPool = void 0;
4const os = require("os");
5const plugin_1 = require("@stryker-mutator/api/plugin");
6const rxjs_1 = require("rxjs");
7const operators_1 = require("rxjs/operators");
8const di_1 = require("./di");
9const Sandbox_1 = require("./Sandbox");
10const MAX_CONCURRENT_INITIALIZING_SANDBOXES = 2;
11let SandboxPool = /** @class */ (() => {
12 class SandboxPool {
13 constructor(log, options, testFramework, initialRunResult, initialFiles, loggingContext, tempDir) {
14 this.log = log;
15 this.options = options;
16 this.testFramework = testFramework;
17 this.initialFiles = initialFiles;
18 this.loggingContext = loggingContext;
19 this.tempDir = tempDir;
20 this.allSandboxes = [];
21 this.runInSandbox = async ([mutant, sandbox]) => {
22 const result = await sandbox.runMutant(mutant);
23 return { result, sandbox };
24 };
25 this.registerSandbox = async (promisedSandbox) => {
26 this.allSandboxes.push(promisedSandbox);
27 return promisedSandbox;
28 };
29 this.isDisposed = false;
30 this.overheadTimeMS = initialRunResult.overheadTimeMS;
31 }
32 runMutants(mutants) {
33 const recycledSandboxes = new rxjs_1.Subject();
34 // Make sure sandboxes get recycled
35 const sandboxes = this.startSandboxes().pipe(operators_1.merge(recycledSandboxes));
36 return mutants.pipe(operators_1.zip(sandboxes), operators_1.flatMap(this.runInSandbox), operators_1.tap(({ sandbox }) => {
37 recycledSandboxes.next(sandbox);
38 }), operators_1.map(({ result }) => result));
39 }
40 startSandboxes() {
41 const concurrency = this.determineConcurrency();
42 return rxjs_1.range(0, concurrency).pipe(operators_1.flatMap(async (n) => {
43 if (this.isDisposed) {
44 return null;
45 }
46 else {
47 return this.registerSandbox(Sandbox_1.default.create(this.options, n, this.initialFiles, this.testFramework, this.overheadTimeMS, this.loggingContext, this.tempDir));
48 }
49 }, MAX_CONCURRENT_INITIALIZING_SANDBOXES), operators_1.filter((sandboxOrNull) => !!sandboxOrNull), operators_1.map((sandbox) => sandbox));
50 }
51 determineConcurrency() {
52 let numConcurrentRunners = os.cpus().length;
53 if (this.options.transpilers.length) {
54 // If transpilers are configured, one core is reserved for the compiler (for now)
55 numConcurrentRunners--;
56 }
57 let numConcurrentRunnersSource = 'CPU count';
58 if (numConcurrentRunners > this.options.maxConcurrentTestRunners && this.options.maxConcurrentTestRunners > 0) {
59 numConcurrentRunners = this.options.maxConcurrentTestRunners;
60 numConcurrentRunnersSource = 'maxConcurrentTestRunners config';
61 }
62 if (numConcurrentRunners <= 0) {
63 numConcurrentRunners = 1;
64 }
65 this.log.info(`Creating ${numConcurrentRunners} test runners (based on ${numConcurrentRunnersSource})`);
66 return numConcurrentRunners;
67 }
68 async dispose() {
69 this.isDisposed = true;
70 const sandboxes = await Promise.all(this.allSandboxes);
71 await Promise.all(sandboxes.map((sandbox) => sandbox.dispose()));
72 }
73 }
74 SandboxPool.inject = plugin_1.tokens(plugin_1.commonTokens.logger, plugin_1.commonTokens.options, di_1.coreTokens.testFramework, di_1.coreTokens.initialRunResult, di_1.coreTokens.transpiledFiles, di_1.coreTokens.loggingContext, di_1.coreTokens.temporaryDirectory);
75 return SandboxPool;
76})();
77exports.SandboxPool = SandboxPool;
78//# sourceMappingURL=SandboxPool.js.map
\No newline at end of file