123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- const configParser_1 = require("./configParser");
- /**
- * The taskScheduler keeps track of the spec files that needs to run next
- * and which task is running what.
- */
- class TaskQueue {
- // A queue of specs for a particular capacity
- constructor(capabilities, specLists) {
- this.capabilities = capabilities;
- this.specLists = specLists;
- this.numRunningInstances = 0;
- this.specsIndex = 0;
- this.maxInstance = capabilities.maxInstances || 1;
- }
- }
- exports.TaskQueue = TaskQueue;
- class TaskScheduler {
- /**
- * A scheduler to keep track of specs that need running and their associated
- * capabilities. It will suggest a task (combination of capabilities and spec)
- * to run while observing the following config rules:
- * multiCapabilities, shardTestFiles, and maxInstance.
- * Precondition: multiCapabilities is a non-empty array
- * (capabilities and getCapabilities will both be ignored)
- *
- * @constructor
- * @param {Object} config parsed from the config file
- */
- constructor(config) {
- this.config = config;
- let excludes = configParser_1.ConfigParser.resolveFilePatterns(config.exclude, true, config.configDir);
- let allSpecs = configParser_1.ConfigParser.resolveFilePatterns(configParser_1.ConfigParser.getSpecs(config), false, config.configDir)
- .filter((path) => {
- return excludes.indexOf(path) < 0;
- });
- let taskQueues = [];
- config.multiCapabilities.forEach((capabilities) => {
- let capabilitiesSpecs = allSpecs;
- if (capabilities.specs) {
- let capabilitiesSpecificSpecs = configParser_1.ConfigParser.resolveFilePatterns(capabilities.specs, false, config.configDir);
- capabilitiesSpecs = capabilitiesSpecs.concat(capabilitiesSpecificSpecs);
- }
- if (capabilities.exclude) {
- let capabilitiesSpecExcludes = configParser_1.ConfigParser.resolveFilePatterns(capabilities.exclude, true, config.configDir);
- capabilitiesSpecs = capabilitiesSpecs.filter((path) => {
- return capabilitiesSpecExcludes.indexOf(path) < 0;
- });
- }
- let specLists = [];
- // If we shard, we return an array of one element arrays, each containing
- // the spec file. If we don't shard, we return an one element array
- // containing an array of all the spec files
- if (capabilities.shardTestFiles) {
- capabilitiesSpecs.forEach((spec) => {
- specLists.push([spec]);
- });
- }
- else {
- specLists.push(capabilitiesSpecs);
- }
- capabilities.count = capabilities.count || 1;
- for (let i = 0; i < capabilities.count; ++i) {
- taskQueues.push(new TaskQueue(capabilities, specLists));
- }
- });
- this.taskQueues = taskQueues;
- this.rotationIndex = 0; // Helps suggestions to rotate amongst capabilities
- }
- /**
- * Get the next task that is allowed to run without going over maxInstance.
- *
- * @return {{capabilities: Object, specs: Array.<string>, taskId: string,
- * done: function()}}
- */
- nextTask() {
- for (let i = 0; i < this.taskQueues.length; ++i) {
- let rotatedIndex = ((i + this.rotationIndex) % this.taskQueues.length);
- let queue = this.taskQueues[rotatedIndex];
- if (queue.numRunningInstances < queue.maxInstance &&
- queue.specsIndex < queue.specLists.length) {
- this.rotationIndex = rotatedIndex + 1;
- ++queue.numRunningInstances;
- let taskId = '' + rotatedIndex + 1;
- if (queue.specLists.length > 1) {
- taskId += '-' + queue.specsIndex;
- }
- let specs = queue.specLists[queue.specsIndex];
- ++queue.specsIndex;
- return {
- capabilities: queue.capabilities,
- specs: specs,
- taskId: taskId,
- done: function () {
- --queue.numRunningInstances;
- }
- };
- }
- }
- return null;
- }
- /**
- * Get the number of tasks left to run or are currently running.
- *
- * @return {number}
- */
- numTasksOutstanding() {
- let count = 0;
- this.taskQueues.forEach((queue) => {
- count += queue.numRunningInstances + (queue.specLists.length - queue.specsIndex);
- });
- return count;
- }
- /**
- * Get maximum number of concurrent tasks required/permitted.
- *
- * @return {number}
- */
- maxConcurrentTasks() {
- if (this.config.maxSessions && this.config.maxSessions > 0) {
- return this.config.maxSessions;
- }
- else {
- let count = 0;
- this.taskQueues.forEach((queue) => {
- count += Math.min(queue.maxInstance, queue.specLists.length);
- });
- return count;
- }
- }
- /**
- * Returns number of tasks currently running.
- *
- * @return {number}
- */
- countActiveTasks() {
- let count = 0;
- this.taskQueues.forEach((queue) => {
- count += queue.numRunningInstances;
- });
- return count;
- }
- }
- exports.TaskScheduler = TaskScheduler;
- //# sourceMappingURL=taskScheduler.js.map
|