UNPKG

postman-runtime

Version:

Underlying library of executing Postman Collections

156 lines (133 loc) 6.04 kB
var _ = require('lodash'), Cursor = require('../cursor'), { getIterationData, prepareVariablesScope, processExecutionResult, prepareVaultVariableScope } = require('../util'); /** * Adds options * disableSNR:Boolean * * @type {Object} */ module.exports = { init: function (done) { var state = this.state; // prepare the vault variable scope and other variables prepareVariablesScope(state); prepareVaultVariableScope(state.vaultSecrets); // ensure that the items and iteration data set is in place !_.isArray(state.items) && (state.items = []); !_.isArray(state.data) && (state.data = []); !_.isObject(state.data[0]) && (state.data[0] = {}); // if the location in state is already normalised then go ahead and queue iteration, else normalise the // location state.cursor = Cursor.box(state.cursor, { // we pass bounds to ensure there is no stale state cycles: this.options.iterationCount, length: state.items.length }); this.waterfall = state.cursor; // copy the location object to instance for quick access // queue the waterfall command if iterations are not parallelized if (!this.areIterationsParallelized) { this.queue('waterfall', { coords: this.waterfall.current(), static: true, start: true }); } // clear the variable that is supposed to store item name and id lookup hash for easy setNextRequest this.snrHash = null; // we populate it in the first SNR call done(); }, triggers: ['beforeIteration', 'iteration'], process: { /** * This processor simply queues scripts and requests in a linear chain. * * @param {Object} payload - * @param {Object} payload.coords - * @param {Boolean} [payload.static=false] - * @param {Function} next - */ waterfall (payload, next) { // we procure the coordinates that we have to pick item and data from. the data is var coords = payload.static ? payload.coords : this.waterfall.whatnext(payload.coords), item = this.state.items[coords.position], delay, isNestedRequest = this.state.nestedRequest !== undefined, rootRequestCursor = isNestedRequest ? this.state.nestedRequest.rootCursor : coords; // if there is nothing to process, we bail out from here, even before we enter the iteration cycle if (coords.empty) { return next(); } if (payload.stopRunNow) { this.triggers.iteration(null, payload.coords); return next(); } // if it is a beginning of a run, we need to raise events for iteration start if (payload.start) { this.triggers.beforeIteration(null, coords); } // if this is a new iteration, we close the previous one and start new if (coords.cr) { // getting the iteration delay here ensures that delay is only called between two iterations delay = _.get(this.options, 'delay.iteration', 0); this.triggers.iteration(null, payload.coords); this.triggers.beforeIteration(null, coords); } // if this is end of waterfall, it is an end of iteration and also end of run if (coords.eof) { this.triggers.iteration(null, coords); return next(); } this.queueDelay(function () { this.queue('item', { item: item, coords: coords, data: getIterationData(this.state.data, isNestedRequest ? rootRequestCursor.iteration : coords.iteration), environment: this.state.environment, globals: this.state.globals, vaultSecrets: this.state.vaultSecrets, collectionVariables: this.state.collectionVariables, _variables: this.state._variables }, function (executionError, executions) { // Use shared utility function to process execution results and handle SNR logic var result = processExecutionResult({ coords: coords, executions: executions, executionError: executionError, runnerOptions: this.options, snrHash: this.snrHash, items: this.state.items }), nextCoords, seekingToStart, stopRunNow; // Update the snrHash if it was created/updated by the utility function this.snrHash = result.snrHash; nextCoords = result.nextCoords; seekingToStart = result.seekingToStart; stopRunNow = result.stopRunNow; this.waterfall.seek(nextCoords.position, nextCoords.iteration, function (err, chngd, coords) { // this condition should never arise, so better throw error when this happens if (err) { throw err; } this.queue('waterfall', { coords: coords, static: seekingToStart, stopRunNow: stopRunNow }); }, this); }); }.bind(this), { time: delay, source: 'iteration', cursor: coords }, next); } } };