[英]azure function unit test cases for retry scenario - nodejs
我已经使用 NodeJs 构建了一个 azure function。 我正在使用 Jest 进行测试。
场景: function拨打API,如果3rd返回Timeout,我需要重试1次后退出。 当实时并且服务器按预期自动重试时,这工作正常。
我未能编写测试用例,因为出现 Jest Timeout 错误。
逻辑:
function.json
"retry": {
"strategy": "exponentialBackoff",
"maxRetryCount": 1,
"minimumInterval": "00:00:10",
"maximumInterval": "00:00:40"
}
index.js - 在 try/catch 下
catch (err) {
let errorCode = err.errorCode || err.code || 500;
let errorMessage = err.message|| err.errorMessage;
if (errorMessage && errorMessage.indexOf("ETIMEDOUT") >= 0 ) {
errorCode = 429; //setting errorCode as 429 to retry automatically from azure function
let retryError = new Error("retrying requests");
retryError.code = 429;
throw retryError;
}else{
context.done();
}
};
索引.test.js
测试套件无法运行重试请求
一旦从主 class 抛出错误,测试 class 将在“ let retryError = new Error("retrying requests"); ”这一行中断。
那么,如果服务器重试耗尽,仍然响应429,如何编写测试用例?
我正在按照这个文档在 Nodejs Azure function 中实现自动化测试。 步骤如下:
要在 VS 代码扩展中测试 Azure function,请使用 Jest。
使用npm i jest
更新package.json以用以下命令替换现有的测试命令
"scripts": {
"test": "jest"
}
对于自动化测试,您可以创建一个模块来运行测试。 创建一个您喜欢的新文件夹 ( testing ) 在创建的文件夹中添加一个新文件 ( defaultContext.js ) 并添加以下命令以记录 function 默认执行上下文。
module.exports = {
log: jest.fn()
};
之后在 HTTP function 触发器文件夹中添加一个新文件index.test.js
并添加以下代码
const httpFunction = require('./index');
const context = require('../testing/defaultContext')
test('Http trigger should return known text', async () => {
const request = {
query: { name: 'Bill' }
};
await httpFunction(context, request);
expect(context.log.mock.calls.length).toBe(1);
expect(context.res.body).toEqual('Hello Bill');
});
使用npm test
命令运行单元测试。
尝试在 azure function 中添加重试策略
在您的触发器中添加重试策略function.json使用固定延迟或指数退避
{
"disabled": false,
"bindings": [
{
....
}
],
"retry": {
"strategy": "exponentialBackoff",
"maxRetryCount": 5,
"minimumInterval": "00:00:10",
"maximumInterval": "00:15:00"
}
}
使用npm test
添加所有运行测试后,我可以看到结果:
重试限制:
在消费计划中,
在重试队列中的最终消息时,应用程序可能会缩小到零。 &
执行重试时,应用程序可能会缩小。 选择重试间隔<= 00:01:00和<= 5次重试以获得更好的结果。
警告不建议将服务总线队列等触发器的传递计数设置为 1,这意味着消息将在单个 function 重试周期后立即被死信。 这是因为触发器通过重试提供弹性,而 function 重试策略是尽最大努力,可能会导致重试总数少于所需的总数。
参考这里
刚刚修改了结构以捕获每个错误,如下所示:
try {
await retry(
async(bail) => {
api_attempt++;
console.log('correlationId:' + correlationId + ' api_attempt:' + api_attempt);
let api_Resp = await myAPI(correlationId, payload)
.catch((error) => {
console.error("correlationId:" + correlationId + " myAPI caught error::", JSON.stringify(error));
let errorCode = error.statusCode;
let errorMessage = error.errorMessage;
let errorDescription = error.errorDescription;
console.log("correlationId:" + correlationId + " myAPI errorCode::" + errorCode);
if (errorCode === 429 ||
(errorMessage && (errorMessage.indexOf("ETIMEDOUT") >= 0 || errorMessage.indexOf("ECONNREFUSED") >= 0 || errorMessage.indexOf("Timeout") >= 0)) ||
(errorDescription && (errorDescription.indexOf("ETIMEDOUT") >= 0 || errorDescription.indexOf("ECONNREFUSED") >= 0 || errorDescription.indexOf("Timeout") >= 0 || errorDescription.indexOf("retries exhausted") >= 0))
) {
console.log("correlationId:" + correlationId + " retrying myAPI");
throw error; //to retry
} else if (errorCode === 500) {
console.log("correlationId:" + correlationId + " exiting myAPI and not writing to db");
return; //don't bail and don't write to DB (as 3Party writes to DB for 500 status)
} else {
// don't retry by bailing error
console.log("correlationId:" + correlationId + " not attempting myAPI retry..");
bail(error);
return;
}
})
}, retryOptions);
} catch (err) {
console.error("correlationId:" + correlationId + " myAPI final error::api_attempt:" + api_attempt + " - retries exhausted while calling API::", JSON.stringify(err));
let errorCode = err.statusCode || 500;
let errorMessage = err.code || err.errorMessage || err.message || err;
let errorDescription = err.statusMessage || err.errorDescription || errorMessage || "Unknown Error at 3Party Single API";
//writing errors to db
callDB(false, correlationId, payload, 'AzureFunction', 'Request failed at 3Party', errorCode, errorMessage, errorDescription);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.