diff --git a/bin/commands/runs.js b/bin/commands/runs.js index 4ee3b1a6..2c19a73c 100644 --- a/bin/commands/runs.js +++ b/bin/commands/runs.js @@ -11,13 +11,14 @@ const archiver = require("../helpers/archiver"), syncRunner = require("../helpers/syncRunner"), checkUploaded = require("../helpers/checkUploaded"), reportGenerator = require('../helpers/reporterHTML').reportGenerator, - {initTimeComponents, markBlockStart, markBlockEnd, getTimeComponents} = require('../helpers/timeComponents'), + {initTimeComponents, instrumentEventTime, markBlockStart, markBlockEnd, getTimeComponents} = require('../helpers/timeComponents'), downloadBuildArtifacts = require('../helpers/buildArtifacts').downloadBuildArtifacts; module.exports = function run(args) { let bsConfigPath = utils.getConfigPath(args.cf); //Delete build_results.txt from log folder if already present. initTimeComponents(); + instrumentEventTime("cliStart") markBlockStart('deleteOldResults'); utils.deleteResults(); markBlockEnd('deleteOldResults'); @@ -168,6 +169,7 @@ module.exports = function run(args) { if(!args.sync) logger.info(Constants.userMessages.EXIT_SYNC_CLI_MESSAGE.replace("", data.build_id)); let dataToSend = { time_components: getTimeComponents(), + unique_id: utils.generateUniqueHash(), build_id: data.build_id, }; if (bsConfig && bsConfig.connection_settings) { diff --git a/bin/helpers/timeComponents.js b/bin/helpers/timeComponents.js index da6216a7..989b99bc 100644 --- a/bin/helpers/timeComponents.js +++ b/bin/helpers/timeComponents.js @@ -2,15 +2,17 @@ const { isUndefined } = require('./utils'); + let sessionTimes = { referenceTimes: { absoluteStartTime: Date.now() }, // Absolute times which needs to be used later to calculate logTimes logTimes: {}, // Time Difference in ms which we need to push to EDS + eventTime: {}, // Time for particular events }; const initTimeComponents = () => { - sessionTimes = {referenceTimes: {absoluteStartTime: Date.now()}, logTimes: {}}; + sessionTimes = {referenceTimes: {absoluteStartTime: Date.now()}, logTimes: {}, eventTime: {}}; }; const markBlockStart = (blockName) => { @@ -26,10 +28,13 @@ const markBlockDiff = (blockName, startTime, stopTime) => { sessionTimes.logTimes[blockName] = stopTime - startTime; } +const instrumentEventTime = (eventName) => { + sessionTimes.eventTime[eventName] = new Date(new Date().toUTCString()); +} + const getTimeComponents = () => { const data = convertDotToNestedObject(sessionTimes.logTimes); - - return data; + return Object.assign(data, sessionTimes.eventTime); }; const convertDotToNestedObject = (dotNotationObject) => { @@ -58,6 +63,7 @@ const convertDotToNestedObject = (dotNotationObject) => { module.exports = { initTimeComponents, + instrumentEventTime, markBlockStart, markBlockEnd, markBlockDiff, diff --git a/bin/helpers/utils.js b/bin/helpers/utils.js index 5499aaf3..10b8c2dd 100644 --- a/bin/helpers/utils.js +++ b/bin/helpers/utils.js @@ -6,6 +6,7 @@ const glob = require('glob'); const getmac = require('getmac').default; const { v4: uuidv4 } = require('uuid'); const browserstack = require('browserstack-local'); +const crypto = require('crypto'); const usageReporting = require("./usageReporting"), logger = require("./logger").winstonLogger, @@ -686,6 +687,18 @@ exports.sanitizeSpecsPattern = (pattern) => { return pattern && pattern.split(",").length > 1 ? "{" + pattern + "}" : pattern; } +exports.generateUniqueHash = () => { + const loopback = /(?:[0]{2}[:-]){5}[0]{2}/ + const interFaceList = os.networkInterfaces(); + for (let inter in interFaceList){ + for (const address of interFaceList[inter]) { + if (loopback.test(address.mac) === false) { + return crypto.createHash('md5').update(address.mac).digest('hex'); + }; + }; + }; +}; + exports.getBrowserCombinations = (bsConfig) => { let osBrowserArray = []; let osBrowser = ""; diff --git a/test/unit/bin/commands/runs.js b/test/unit/bin/commands/runs.js index 9de0e885..ffca3fef 100644 --- a/test/unit/bin/commands/runs.js +++ b/test/unit/bin/commands/runs.js @@ -647,6 +647,7 @@ describe("runs", () => { setUsernameStub = sandbox.stub(); setAccessKeyStub = sandbox.stub(); setBuildNameStub = sandbox.stub(); + generateUniqueHashStub = sandbox.stub().returns('random_hash'); setCypressConfigFilenameStub = sandbox.stub(); setUserSpecsStub = sandbox.stub(); setTestEnvsStub = sandbox.stub(); @@ -678,6 +679,7 @@ describe("runs", () => { setLocalConfigFileStub = sandbox.stub(); getTimeComponentsStub = sandbox.stub().returns({}); initTimeComponentsStub = sandbox.stub(); + instrumentEventTimeStub = sandbox.stub(); markBlockStartStub = sandbox.stub(); markBlockEndStub = sandbox.stub(); setConfigStub = sandbox.stub(); @@ -696,7 +698,7 @@ describe("runs", () => { let errorCode = null; let message = `Success! ${Constants.userMessages.BUILD_CREATED} with build id: random_build_id`; let dashboardLink = `${Constants.userMessages.VISIT_DASHBOARD} ${dashboardUrl}`; - let data = {time_components: {}, build_id: 'random_build_id'} + let data = {time_components: {}, unique_id: 'random_hash', build_id: 'random_build_id'} const runs = proxyquire('../../../../bin/commands/runs', { '../helpers/utils': { @@ -720,6 +722,7 @@ describe("runs", () => { setHeaded: setHeadedStub, setNoWrap: setNoWrapStub, setOtherConfigs: setOtherConfigsStub, + generateUniqueHash: generateUniqueHashStub, exportResults: exportResultsStub, deleteResults: deleteResultsStub, setDefaults: setDefaultsStub, @@ -754,6 +757,7 @@ describe("runs", () => { }, '../helpers/timeComponents': { initTimeComponents: initTimeComponentsStub, + instrumentEventTime: instrumentEventTimeStub, getTimeComponents: getTimeComponentsStub, markBlockStart: markBlockStartStub, markBlockEnd: markBlockEndStub, @@ -792,6 +796,7 @@ describe("runs", () => { sinon.assert.calledOnce(setHeadedStub); sinon.assert.calledOnce(setNoWrapStub); sinon.assert.calledOnce(setOtherConfigsStub); + sinon.assert.calledOnce(generateUniqueHashStub); sinon.assert.calledOnce(archiverStub); sinon.assert.calledOnce(setUsageReportingFlagStub); sinon.assert.calledOnce(zipUploadStub); diff --git a/test/unit/bin/helpers/timeComponents.js b/test/unit/bin/helpers/timeComponents.js index d09f8c66..64b35c6e 100644 --- a/test/unit/bin/helpers/timeComponents.js +++ b/test/unit/bin/helpers/timeComponents.js @@ -8,6 +8,7 @@ const chai = require("chai"), let timeComponents = rewire('../../../../bin/helpers/timeComponents'); let initTimeComponents = timeComponents.__get__('initTimeComponents'); +let instrumentEventTime = timeComponents.__get__('instrumentEventTime'); let markBlockStart = timeComponents.__get__('markBlockStart'); let markBlockEnd = timeComponents.__get__('markBlockEnd'); let markBlockDiff = timeComponents.__get__('markBlockDiff'); @@ -24,6 +25,15 @@ describe('timeComponents', () => { }); }); + describe('instrumentEventTime', () => { + it('should set reset sessionTimes object', () => { + initTimeComponents(); + instrumentEventTime('cliTest'); + let sessionTimes = timeComponents.__get__('sessionTimes'); + expect(Object.keys(sessionTimes.eventTime)).to.include('cliTest'); + }); + }); + describe('markBlockStart', () => { it('should add key to reference times', () => { initTimeComponents(); @@ -86,7 +96,6 @@ describe('timeComponents', () => { it('should call convertDotToNestedObject and return data', () => { let convertDotToNestedObjectStub = sinon.stub().returns({sampleBlock: 100}), convertDotToNestedObjectUnset = timeComponents.__set__('convertDotToNestedObject', convertDotToNestedObjectStub); - expect(getTimeComponents()).to.deep.equal({sampleBlock:100}); convertDotToNestedObjectUnset(); diff --git a/test/unit/bin/helpers/utils.js b/test/unit/bin/helpers/utils.js index 5aa77831..a75b8c9e 100644 --- a/test/unit/bin/helpers/utils.js +++ b/test/unit/bin/helpers/utils.js @@ -9,6 +9,8 @@ const chai = require('chai'), chaiAsPromised = require('chai-as-promised'), glob = require('glob'), chalk = require('chalk'), + os = require("os"), + crypto = require('crypto'), fs = require('fs'); const getmac = require('getmac').default; const usageReporting = require('../../../../bin/helpers/usageReporting'); @@ -2248,6 +2250,63 @@ describe('utils', () => { }); }); + describe('generateUniqueHash', () => { + beforeEach(() => { + let interfaceList = { + lo0: [ + { + address: 'fe80::1', + netmask: 'ffff:ffff:ffff:ffff::', + family: 'IPv6', + mac: '00:00:00:00:00:00', + internal: true, + cidr: 'fe80::1/64', + scopeid: 1 + } + ], + en5: [ + { + address: 'fe80::1', + netmask: 'ffff:ffff:ffff:ffff::', + family: 'IPv6', + mac: '00:00:00:00:00:00', + internal: true, + cidr: 'fe80::1/64', + scopeid: 1 + }, + { + address: 'fe80::aede:48ff:fe00:1122', + netmask: 'ffff:ffff:ffff:ffff::', + family: 'IPv6', + mac: 'ra:nd:om:01:23:45', + internal: false, + cidr: 'fe80::aede:48ff:fe00:1122/64', + scopeid: 7 + } + ], + en0: [ + { + address: '192.168.29.250', + netmask: '255.255.255.0', + family: 'IPv4', + mac: '00:00:00:00:00:00', + internal: false, + cidr: '192.168.29.250/24' + } + ] + }; + sinon.stub(os, 'networkInterfaces').returns(interfaceList); + sinon.stub(crypto, 'createHash').returns({ + update: sinon.stub().returns({ + digest: sinon.stub().returns("random_hash") + }) + }); + }); + it('should return non zero mac address', () => { + expect(utils.generateUniqueHash()).to.equal('random_hash'); + }); + }); + describe('setBrowsers', () => { it('the args browser should override the bsconfig browsers', async () => { let bsConfig = {