Skip to content
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

fix: redirect chains with capture/afterResponse hooks #1568

Merged
merged 6 commits into from
Aug 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 30 additions & 49 deletions core/lib/engine_http.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ const { HttpsAgent } = HttpAgent;
const { HttpProxyAgent, HttpsProxyAgent } = require('hpagent');
const decompressResponse = require('decompress-response');

const { promisify } = require('node:util');

module.exports = HttpEngine;

const DEFAULT_AGENT_OPTIONS = {
Expand Down Expand Up @@ -104,7 +106,7 @@ function HttpEngine(script) {

if (
(script.config.http && script.config.http.extendedMetrics === true) ||
global.artillery.runtimeOptions.extendedHTTPMetrics
global.artillery?.runtimeOptions.extendedHTTPMetrics
) {
this.extendedHTTPMetrics = true;
}
Expand Down Expand Up @@ -202,9 +204,6 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
let processFunc = self.config.processor[requestSpec.function];
if (processFunc) {
return processFunc(context, ee, function (hookErr) {
if (hookErr) {
ee.emit('error', hookErr.code || hookErr.message);
}
return callback(hookErr, context);
});
} else {
Expand All @@ -219,12 +218,6 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
}

let f = function (context, callback) {
// Previous request had an error of the kind that should stop current VU
if (context.error) {
ee.emit('error', err.message || err.code);
return callback(context.error, context);
}

let method = _.keys(requestSpec)[0].toUpperCase();
let params = requestSpec[method.toLowerCase()];

Expand All @@ -236,7 +229,6 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
// This will be obsoleted by better script validation.
if (!params.url && !params.uri) {
let err = new Error('an URL must be specified');
ee.emit('error', err.message);
return callback(err, context);
}

Expand Down Expand Up @@ -310,9 +302,6 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
function done(err) {
if (err) {
debug(err);
let errCode = err.code || err.message;
// FIXME: Should not need to have to emit manually here
ee.emit('error', errCode);
return callback(err, context);
}

Expand Down Expand Up @@ -345,9 +334,6 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
// Follow all redirects by default unless specified otherwise
if (typeof requestParams.followRedirect === 'undefined') {
requestParams.followRedirect = true;
requestParams.followAllRedirects = true;
} else if (requestParams.followRedirect === false) {
requestParams.followAllRedirects = false;
}

// TODO: Use traverse on the entire flow instead
Expand Down Expand Up @@ -450,15 +436,10 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {

if (!requestParams.url || !requestParams.url.startsWith('http')) {
let err = new Error(`Invalid URL - ${requestParams.url}`);
ee.emit('error', err.message);
return callback(err, context);
}

function responseProcessor(err, res, body, done) {
if (err) {
return;
}

function responseProcessor(isLast, res, body, done) {
if (process.env.DEBUG) {
let requestInfo = {
url: requestParams.url,
Expand Down Expand Up @@ -514,6 +495,11 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
debugResponse(JSON.stringify(res.headers, null, 2));
debugResponse(JSON.stringify(body, null, 2));

// capture/match/response hooks run only for last request in a task
if(!isLast) {
return done(null, context);
}

const resForCapture = { headers: res.headers, body: body };
engineUtil.captureOrMatch(
params,
Expand All @@ -530,7 +516,6 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
context,
ee,
function (asyncErr) {
ee.emit('error', err.message);
return done(err, context);
}
);
Expand Down Expand Up @@ -588,7 +573,7 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
let processFunc = config.processor[fn];
if (!processFunc) {
// TODO: DRY - #223
processFunc = function (r, c, e, cb) {
processFunc = function (r, res, c, e, cb) {
return cb(null);
};
console.log(
Expand All @@ -609,7 +594,6 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
function (err) {
if (err) {
debug(err);
ee.emit('error', err.code || err.message);
return done(err, context);
}

Expand Down Expand Up @@ -651,7 +635,6 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
context,
ee,
function (asyncErr) {
ee.emit('error', err.message);
return callback(err, context);
}
);
Expand Down Expand Up @@ -692,15 +675,12 @@ HttpEngine.prototype.step = function step(requestSpec, ee, opts) {
context,
ee,
function (asyncErr) {
let errCode = err.code || err.message;
ee.emit('error', errCode);
return callback(err, context);
}
);
})
.catch((gotErr) => {
// TODO: Handle the error properly with run hooks
ee.emit('error', gotErr.code || gotErr.message);
return callback(gotErr, context);
});
}
Expand Down Expand Up @@ -759,18 +739,23 @@ HttpEngine.prototype._handleResponse = function (

context._successCount++;

// config.defaults won't be taken into account for this
const isLastRequest = lastRequest(res, requestParams);

if (responseProcessor) {
responseProcessor(null, res, body, (processResponseErr) => {
responseProcessor(isLastRequest, res, body, (processResponseErr) => {
// capture/match returned an error object, or a hook function returned
// with an error
if (processResponseErr) {
context.error = processResponseErr;
return callback(processResponseErr, context);
}

if (lastRequest(res, requestParams)) {
if (isLastRequest) {
return callback(null, context);
}
});
} else {
if (lastRequest(res, requestParams)) {
if (isLastRequest) {
return callback(null, context);
}
}
Expand Down Expand Up @@ -827,23 +812,19 @@ HttpEngine.prototype.setInitialContext = function (initialContext) {
HttpEngine.prototype.compile = function compile(tasks, scenarioSpec, ee) {
let self = this;

return function scenario(initialContext, callback) {
return async function scenario(initialContext, callback) {
initialContext = self.setInitialContext(initialContext);
let steps = _.flatten([
function zero(cb) {
ee.emit('started');
return cb(null, initialContext);
},
tasks
]);

async.waterfall(steps, function scenarioWaterfallCb(err, context) {
if (err) {
return callback(err, context);
} else {
return callback(null, context);
ee.emit('started');
let context = initialContext;
for (const task of tasks) {
try {
context = await promisify(task)(context);
} catch (taskErr) {
ee.emit('error', taskErr.code || taskErr.message);
return callback(taskErr, context); // calling back for now for existing client code
}
});
}
return callback(null, context);
};
};

Expand Down
12 changes: 11 additions & 1 deletion test/core/unit/engine_http.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -610,7 +610,17 @@ test('HTTP engine', function (tap) {
},
scenarios: [
{
flow: [{ get: { url: '/foo' } }]
flow: [
{
get: {
url: '/foo',
capture: {
json: '$',
as: 'jsonBody'
}
}
}
]
}
]
};
Expand Down