Skip to content

Limiting the allocation of parallels w.r.t specs . #85

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Nov 20, 2020
8 changes: 5 additions & 3 deletions bin/commands/runs.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,13 @@ module.exports = function run(args) {
utils.setLocalIdentifier(bsConfig);

// Validate browserstack.json values and parallels specified via arguments
return capabilityHelper.validate(bsConfig, args).then(function (validated) {
logger.info(validated);
return capabilityHelper.validate(bsConfig, args).then(function (cypressJson) {

//get the number of spec files
let specFiles = utils.getNumberOfSpecFiles(bsConfig, args, cypressJson);

// accept the number of parallels
utils.setParallels(bsConfig, args);
utils.setParallels(bsConfig, args, specFiles.length);

// Archive the spec files
return archiver.archive(bsConfig.run_settings, config.fileName, args.exclude).then(function (data) {
Expand Down
4 changes: 2 additions & 2 deletions bin/helpers/capabilityHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ const validate = (bsConfig, args) => {
// validate if config file provided exists or not when cypress_config_file provided
// validate the cypressProjectDir key otherwise.
let cypressConfigFilePath = bsConfig.run_settings.cypressConfigFilePath;
let cypressJson = {};

if (!fs.existsSync(cypressConfigFilePath) && bsConfig.run_settings.cypress_config_filename !== 'false') reject(Constants.validationMessages.INVALID_CYPRESS_CONFIG_FILE);

Expand All @@ -140,8 +141,7 @@ const validate = (bsConfig, args) => {
} catch(error){
reject(Constants.validationMessages.INVALID_CYPRESS_JSON)
}

resolve(Constants.validationMessages.VALIDATED);
resolve(cypressJson);
});
}

Expand Down
8 changes: 7 additions & 1 deletion bin/helpers/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,17 @@ const allowedFileTypes = ['js', 'json', 'txt', 'ts', 'feature', 'features', 'pdf

const filesToIgnoreWhileUploading = ['**/node_modules/**', 'node_modules/**', 'package-lock.json', 'package.json', 'browserstack-package.json', 'tests.zip', 'cypress.json']

const specFileTypes = ['js', 'ts', 'feature']

const DEFAULT_CYPRESS_SPEC_PATH = "cypress/integration"

module.exports = Object.freeze({
userMessages,
cliMessages,
validationMessages,
messageTypes,
allowedFileTypes,
filesToIgnoreWhileUploading
filesToIgnoreWhileUploading,
specFileTypes,
DEFAULT_CYPRESS_SPEC_PATH
});
37 changes: 36 additions & 1 deletion bin/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
const os = require("os");
const path = require("path");
const fs = require("fs");
const glob = require('glob');

const usageReporting = require("./usageReporting"),
logger = require("./logger").winstonLogger,
Expand Down Expand Up @@ -109,10 +110,22 @@ exports.setUsageReportingFlag = (bsConfig, disableUsageReporting) => {
}
};

exports.setParallels = (bsConfig, args) => {
exports.setParallels = (bsConfig, args, numOfSpecs) => {
if (!this.isUndefined(args.parallels)) {
bsConfig["run_settings"]["parallels"] = args.parallels;
}
let browserCombinations = this.getBrowserCombinations(bsConfig);
let maxParallels = browserCombinations.length * numOfSpecs;
if (numOfSpecs <= 0) {
bsConfig['run_settings']['parallels'] = browserCombinations.length;
return;
}
if (bsConfig['run_settings']['parallels'] > maxParallels && bsConfig['run_settings']['parallels'] != -1 ) {
logger.warn(
`Using ${maxParallels} machines instead of ${bsConfig['run_settings']['parallels']} that you configured as there are ${numOfSpecs} specs to be run on ${browserCombinations.length} browser combinations.`
);
bsConfig['run_settings']['parallels'] = maxParallels;
}
};

exports.setDefaults = (bsConfig, args) => {
Expand Down Expand Up @@ -316,3 +329,25 @@ exports.setLocalIdentifier = (bsConfig) => {
);
}
};

exports.getNumberOfSpecFiles = (bsConfig, args, cypressJson) => {
let testFolderPath = cypressJson.integrationFolder || Constants.DEFAULT_CYPRESS_SPEC_PATH;
let globSearchPatttern = bsConfig.run_settings.specs || `${testFolderPath}/**/*.+(${Constants.specFileTypes.join("|")})`;
let ignoreFiles = args.exclude || bsConfig.run_settings.exclude;
let files = glob.sync(globSearchPatttern, {cmd: bsConfig.run_settings.cypressConfigFilePath, matchBase: true, ignore: ignoreFiles});
return files;
};

exports.getBrowserCombinations = (bsConfig) => {
let osBrowserArray = [];
let osBrowser = "";
if (bsConfig.browsers) {
bsConfig.browsers.forEach((element) => {
osBrowser = element.os + '-' + element.browser;
element.versions.forEach((version) => {
osBrowserArray.push(osBrowser + version);
});
});
}
return osBrowserArray;
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
"request": "^2.88.0",
"requestretry": "^4.1.0",
"winston": "^2.3.1",
"yargs": "^14.2.2"
"yargs": "^14.2.2",
"glob": "^7.1.6"
},
"repository": {
"type": "git",
Expand Down
32 changes: 22 additions & 10 deletions test/unit/bin/commands/runs.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ describe("runs", () => {
setLocalStub = sandbox.stub();
setLocalIdentifierStub = sandbox.stub();
deleteResultsStub = sandbox.stub();
getNumberOfSpecFilesStub = sandbox.stub().returns([]);
setDefaultsStub = sandbox.stub();
});

Expand Down Expand Up @@ -217,7 +218,8 @@ describe("runs", () => {
setLocal: setLocalStub,
setLocalIdentifier: setLocalIdentifierStub,
deleteResults: deleteResultsStub,
setDefaults: setDefaultsStub
setDefaults: setDefaultsStub,
getNumberOfSpecFiles: getNumberOfSpecFilesStub
},
'../helpers/capabilityHelper': {
validate: capabilityValidatorStub,
Expand All @@ -241,6 +243,7 @@ describe("runs", () => {
.catch((error) => {
sinon.assert.calledOnce(getConfigPathStub);
sinon.assert.calledOnce(getConfigPathStub);
sinon.assert.calledOnce(getNumberOfSpecFilesStub);
sinon.assert.calledOnce(setParallelsStub);
sinon.assert.calledOnce(setLocalStub);
sinon.assert.calledOnce(setLocalIdentifierStub);
Expand Down Expand Up @@ -288,6 +291,7 @@ describe("runs", () => {
setLocalStub = sandbox.stub();
setLocalIdentifierStub = sandbox.stub();
deleteResultsStub = sandbox.stub();
getNumberOfSpecFilesStub = sandbox.stub().returns([]);
setDefaultsStub = sandbox.stub();
});

Expand Down Expand Up @@ -317,6 +321,7 @@ describe("runs", () => {
setLocal: setLocalStub,
setLocalIdentifier: setLocalIdentifierStub,
deleteResults: deleteResultsStub,
getNumberOfSpecFiles: getNumberOfSpecFilesStub,
setDefaults: setDefaultsStub
},
'../helpers/capabilityHelper': {
Expand Down Expand Up @@ -345,6 +350,7 @@ describe("runs", () => {
.catch((error) => {
sinon.assert.calledOnce(getConfigPathStub);
sinon.assert.calledOnce(getConfigPathStub);
sinon.assert.calledOnce(getNumberOfSpecFilesStub);
sinon.assert.calledOnce(setParallelsStub);
sinon.assert.calledOnce(setLocalStub);
sinon.assert.calledOnce(setLocalIdentifierStub);
Expand Down Expand Up @@ -396,6 +402,7 @@ describe("runs", () => {
setLocalStub = sandbox.stub();
setLocalIdentifierStub = sandbox.stub();
deleteResultsStub = sandbox.stub();
getNumberOfSpecFilesStub = sandbox.stub().returns([]);
setDefaultsStub = sandbox.stub();
});

Expand Down Expand Up @@ -425,6 +432,7 @@ describe("runs", () => {
setLocal: setLocalStub,
setLocalIdentifier: setLocalIdentifierStub,
deleteResults: deleteResultsStub,
getNumberOfSpecFiles: getNumberOfSpecFilesStub,
setDefaults: setDefaultsStub
},
'../helpers/capabilityHelper': {
Expand Down Expand Up @@ -461,6 +469,7 @@ describe("runs", () => {
sinon.assert.calledOnce(getConfigPathStub);
sinon.assert.calledOnce(validateBstackJsonStub);
sinon.assert.calledOnce(capabilityValidatorStub);
sinon.assert.calledOnce(getNumberOfSpecFilesStub);
sinon.assert.calledOnce(setParallelsStub);
sinon.assert.calledOnce(setLocalStub);
sinon.assert.calledOnce(setLocalIdentifierStub);
Expand Down Expand Up @@ -519,6 +528,7 @@ describe("runs", () => {
isUndefinedStub = sandbox.stub();
setLocalStub = sandbox.stub();
setLocalIdentifierStub = sandbox.stub();
getNumberOfSpecFilesStub = sandbox.stub().returns([]);
});

afterEach(() => {
Expand All @@ -532,8 +542,8 @@ describe("runs", () => {
let message = `Success! ${Constants.userMessages.BUILD_CREATED} with build id: random_build_id`;
let dashboardLink = `${Constants.userMessages.VISIT_DASHBOARD} ${dashboardUrl}random_build_id`;

const runs = proxyquire("../../../../bin/commands/runs", {
"../helpers/utils": {
const runs = proxyquire('../../../../bin/commands/runs', {
'../helpers/utils': {
validateBstackJson: validateBstackJsonStub,
sendUsageReport: sendUsageReportStub,
setUsername: setUsernameStub,
Expand All @@ -550,24 +560,25 @@ describe("runs", () => {
exportResults: exportResultsStub,
deleteResults: deleteResultsStub,
setDefaults: setDefaultsStub,
isUndefined: isUndefinedStub
isUndefined: isUndefinedStub,
getNumberOfSpecFiles: getNumberOfSpecFilesStub
},
"../helpers/capabilityHelper": {
'../helpers/capabilityHelper': {
validate: capabilityValidatorStub,
},
"../helpers/archiver": {
'../helpers/archiver': {
archive: archiverStub,
},
"../helpers/fileHelpers": {
'../helpers/fileHelpers': {
deleteZip: deleteZipStub,
},
"../helpers/zipUpload": {
'../helpers/zipUpload': {
zipUpload: zipUploadStub,
},
"../helpers/build": {
'../helpers/build': {
createBuild: createBuildStub,
},
"../helpers/config": {
'../helpers/config': {
dashboardUrl: dashboardUrl,
},
});
Expand All @@ -589,6 +600,7 @@ describe("runs", () => {
sinon.assert.calledOnce(getConfigPathStub);
sinon.assert.calledOnce(validateBstackJsonStub);
sinon.assert.calledOnce(capabilityValidatorStub);
sinon.assert.calledOnce(getNumberOfSpecFilesStub);
sinon.assert.calledOnce(setParallelsStub);
sinon.assert.calledOnce(setLocalStub);
sinon.assert.calledOnce(setLocalIdentifierStub);
Expand Down
30 changes: 6 additions & 24 deletions test/unit/bin/helpers/capabilityHelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -561,10 +561,7 @@ describe("capabilityHelper.js", () => {
return capabilityHelper
.validate(bsConfig, { parallels: undefined })
.then(function (data) {
chai.assert.equal(data, Constants.validationMessages.VALIDATED);
})
.catch((error) => {
chai.assert.fail("Promise error");
chai.assert.deepEqual(data, {});
});
});

Expand All @@ -574,10 +571,7 @@ describe("capabilityHelper.js", () => {
return capabilityHelper
.validate(bsConfig, { parallels: undefined })
.then(function (data) {
chai.assert.equal(data, Constants.validationMessages.VALIDATED);
})
.catch((error) => {
chai.assert.fail("Promise error");
chai.assert.deepEqual(data, {});
});
});

Expand All @@ -586,10 +580,7 @@ describe("capabilityHelper.js", () => {
return capabilityHelper
.validate(bsConfig, { parallels: 200 })
.then(function (data) {
chai.assert.equal(data, Constants.validationMessages.VALIDATED);
})
.catch((error) => {
chai.assert.fail("Promise error");
chai.assert.deepEqual(data, {});
});
});

Expand All @@ -598,10 +589,7 @@ describe("capabilityHelper.js", () => {
return capabilityHelper
.validate(bsConfig, { parallels: -1 })
.then(function (data) {
chai.assert.equal(data, Constants.validationMessages.VALIDATED);
})
.catch((error) => {
chai.assert.fail("Promise error");
chai.assert.deepEqual(data, {});
});
});

Expand All @@ -611,10 +599,7 @@ describe("capabilityHelper.js", () => {
return capabilityHelper
.validate(bsConfig, { parallels: -1 })
.then(function (data) {
chai.assert.equal(data, Constants.validationMessages.VALIDATED);
})
.catch((error) => {
chai.assert.fail("Promise error");
chai.assert.deepEqual(data, {});
});
});

Expand All @@ -624,10 +609,7 @@ describe("capabilityHelper.js", () => {
return capabilityHelper
.validate(bsConfig, { parallels: -1 })
.then(function (data) {
chai.assert.equal(data, Constants.validationMessages.VALIDATED);
})
.catch((error) => {
chai.assert.fail("Promise error");
chai.assert.deepEqual(data, {});
});
});
});
Expand Down
Loading